diff options
Diffstat (limited to 'chrome/browser/ui/panels')
-rw-r--r-- | chrome/browser/ui/panels/detached_panel_browsertest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/docked_panel_browsertest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_and_desktop_notification_browsertest.cc | 6 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_browsertest.cc | 11 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_drag_browsertest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_drag_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_gtk.cc | 1173 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_gtk.h | 235 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_host.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_host.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_resize_browsertest.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_titlebar_gtk.cc | 311 | ||||
-rw-r--r-- | chrome/browser/ui/panels/panel_titlebar_gtk.h | 98 |
15 files changed, 38 insertions, 1832 deletions
diff --git a/chrome/browser/ui/panels/detached_panel_browsertest.cc b/chrome/browser/ui/panels/detached_panel_browsertest.cc index 2fab8c0b..901560a 100644 --- a/chrome/browser/ui/panels/detached_panel_browsertest.cc +++ b/chrome/browser/ui/panels/detached_panel_browsertest.cc @@ -9,6 +9,9 @@ #include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel_manager.h" +// Refactor has only been done for Win and Mac panels so far. +#if defined(OS_WIN) || defined(OS_MACOSX) + class DetachedPanelBrowserTest : public BasePanelBrowserTest { }; @@ -142,3 +145,5 @@ IN_PROC_BROWSER_TEST_F(DetachedPanelBrowserTest, ClickTitlebar) { panel_manager->CloseAll(); } + +#endif // OS_WIN || OS_MACOSX diff --git a/chrome/browser/ui/panels/docked_panel_browsertest.cc b/chrome/browser/ui/panels/docked_panel_browsertest.cc index f5baac5..e16cd9a 100644 --- a/chrome/browser/ui/panels/docked_panel_browsertest.cc +++ b/chrome/browser/ui/panels/docked_panel_browsertest.cc @@ -11,6 +11,9 @@ #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" +// Refactor has only been done for Win and Mac panels so far. +#if defined(OS_WIN) || defined(OS_MACOSX) + class DockedPanelBrowserTest : public BasePanelBrowserTest { public: virtual void SetUpOnMainThread() OVERRIDE { @@ -265,3 +268,5 @@ IN_PROC_BROWSER_TEST_F(DockedPanelBrowserTest, CloseSqueezedPanels) { panel_manager->CloseAll(); } + +#endif // OS_WIN || OS_MACOSX diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index b4ebc4c..1f63a80 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -102,7 +102,6 @@ bool PanelExtensionWindowController::IsVisibleToExtension( Panel::Panel(const std::string& app_name, const gfx::Size& min_size, const gfx::Size& max_size) : app_name_(app_name), - profile_(NULL), panel_strip_(NULL), initialized_(false), min_size_(min_size), @@ -143,7 +142,6 @@ void Panel::Initialize(Profile* profile, const GURL& url, DCHECK_EQ(EXPANDED, expansion_state_); DCHECK(!bounds.IsEmpty()); initialized_ = true; - profile_ = profile; full_size_ = bounds.size(); native_panel_ = CreateNativePanel(this, bounds); @@ -217,7 +215,7 @@ CommandUpdater* Panel::command_updater() { } Profile* Panel::profile() const { - return profile_; + return extension_window_controller_->profile(); } const std::string Panel::extension_id() const { diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h index 8fd099e..edf01e7 100644 --- a/chrome/browser/ui/panels/panel.h +++ b/chrome/browser/ui/panels/panel.h @@ -336,8 +336,6 @@ class Panel : public BaseWindow, // This name should be set when the panel is created. const std::string app_name_; - Profile* profile_; - // Current collection of panels to which this panel belongs. This determines // the panel's screen layout. PanelStrip* panel_strip_; // Owned by PanelManager. diff --git a/chrome/browser/ui/panels/panel_and_desktop_notification_browsertest.cc b/chrome/browser/ui/panels/panel_and_desktop_notification_browsertest.cc index 3cf1377..981bf03 100644 --- a/chrome/browser/ui/panels/panel_and_desktop_notification_browsertest.cc +++ b/chrome/browser/ui/panels/panel_and_desktop_notification_browsertest.cc @@ -18,6 +18,10 @@ #include "content/public/common/show_desktop_notification_params.h" #include "ui/gfx/screen.h" + +// Refactor has only been done for Win and Mac panels so far. +#if defined(OS_WIN) || defined(OS_MACOSX) + // Desktop notification code subscribes to various panel change notifications // so that it knows when to adjusts balloon positions. In order to give // desktop notification code a chance to process the change notifications, @@ -399,3 +403,5 @@ IN_PROC_BROWSER_TEST_F(PanelAndDesktopNotificationTest, InteractWithTwoPanels) { MessageLoopForUI::current()->RunAllPending(); EXPECT_EQ(original_balloon_bottom, GetBalloonBottomPosition(balloon)); } + +#endif // OS_WIN || OS_MACOSX diff --git a/chrome/browser/ui/panels/panel_browsertest.cc b/chrome/browser/ui/panels/panel_browsertest.cc index 9003471..b14a5fb 100644 --- a/chrome/browser/ui/panels/panel_browsertest.cc +++ b/chrome/browser/ui/panels/panel_browsertest.cc @@ -24,7 +24,6 @@ #include "chrome/browser/ui/panels/native_panel.h" #include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel_manager.h" -#include "chrome/browser/ui/panels/test_panel_active_state_observer.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/common/chrome_notification_types.h" @@ -43,6 +42,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/screen.h" +// Refactor has only been done for Win and Mac panels so far. +#if defined(OS_WIN) || defined(OS_MACOSX) + using content::BrowserContext; using content::BrowserThread; using content::DownloadItem; @@ -1273,9 +1275,9 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserTest, FocusLostOnMinimize) { Panel* panel = CreatePanelWithParams(params); EXPECT_EQ(Panel::EXPANDED, panel->expansion_state()); - PanelActiveStateObserver signal(panel, false); - panel->Minimize(); - signal.Wait(); + panel->SetExpansionState(Panel::MINIMIZED); + MessageLoop::current()->RunAllPending(); + WaitForPanelActiveState(panel, SHOW_AS_INACTIVE); panel->Close(); } @@ -1591,3 +1593,4 @@ IN_PROC_BROWSER_TEST_F(PanelBrowserTest, MAYBE_Accelerator) { EXPECT_EQ(0, panel_manager->num_panels()); } +#endif // OS_WIN || OS_MACOSX diff --git a/chrome/browser/ui/panels/panel_drag_browsertest.cc b/chrome/browser/ui/panels/panel_drag_browsertest.cc index e87e878..3a9e5b1 100644 --- a/chrome/browser/ui/panels/panel_drag_browsertest.cc +++ b/chrome/browser/ui/panels/panel_drag_browsertest.cc @@ -11,6 +11,9 @@ #include "chrome/browser/ui/panels/panel_drag_controller.h" #include "chrome/browser/ui/panels/panel_manager.h" +// Refactor has only been done for Win and Mac panels so far. +#if defined(OS_WIN) || defined(OS_MACOSX) + class PanelDragBrowserTest : public BasePanelBrowserTest { public: PanelDragBrowserTest() : BasePanelBrowserTest() { @@ -1337,3 +1340,5 @@ IN_PROC_BROWSER_TEST_F(PanelDragBrowserTest, DragDetachedPanelToTop) { panel_manager->CloseAll(); } + +#endif // OS_WIN || OS_MACOSX diff --git a/chrome/browser/ui/panels/panel_drag_gtk.h b/chrome/browser/ui/panels/panel_drag_gtk.h index 2d39333..a70e062 100644 --- a/chrome/browser/ui/panels/panel_drag_gtk.h +++ b/chrome/browser/ui/panels/panel_drag_gtk.h @@ -43,8 +43,7 @@ class PanelDragGtk { GtkWidget* titlebar_widget); private: - friend class NativePanelTestingGtk; // legacy - friend class GtkNativePanelTesting; + friend class NativePanelTestingGtk; enum DragState { NOT_DRAGGING, diff --git a/chrome/browser/ui/panels/panel_gtk.cc b/chrome/browser/ui/panels/panel_gtk.cc index 59bfebc..eeb6039 100644 --- a/chrome/browser/ui/panels/panel_gtk.cc +++ b/chrome/browser/ui/panels/panel_gtk.cc @@ -2,1180 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/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.h" -#include "base/utf_string_conversions.h" -#include "chrome/app/chrome_command_ids.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_theme_service.h" -#include "chrome/browser/ui/gtk/gtk_util.h" -#include "chrome/browser/ui/gtk/gtk_window_util.h" #include "chrome/browser/ui/panels/panel.h" -#include "chrome/browser/ui/panels/panel_bounds_animation.h" -#include "chrome/browser/ui/panels/panel_titlebar_gtk.h" -#include "chrome/browser/ui/panels/panel_constants.h" -#include "chrome/browser/ui/panels/panel_drag_gtk.h" -#include "chrome/browser/ui/panels/panel_manager.h" -#include "chrome/browser/web_applications/web_app.h" -#include "chrome/common/chrome_notification_types.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 "grit/theme_resources.h" -#include "grit/ui_resources.h" -#include "ui/base/accelerators/accelerator_gtk.h" -#include "ui/base/gtk/gtk_compat.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/gfx/canvas.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(0xff, 0xab, 0x57); -const SkColor kMinimizeBackgroundDefaultColor = SkColorSetRGB(0xf5, 0xf4, 0xf0); -const SkColor kMinimizeBorderDefaultColor = SkColorSetRGB(0xc9, 0xc9, 0xc9); - -// Color used to draw the divider line between the titlebar and the client area. -const SkColor kDividerColor = SkColorSetRGB(0x2a, 0x2c, 0x2c); - -// 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 }, -}; - -// Table of accelerator mappings to command ids. -typedef std::map<ui::AcceleratorGtk, int> AcceleratorGtkMap; - -const AcceleratorGtkMap& GetAcceleratorTable() { - CR_DEFINE_STATIC_LOCAL(AcceleratorGtkMap, accelerator_table, ()); - if (accelerator_table.empty()) { - for (size_t i = 0; i < arraysize(kAcceleratorMap); ++i) { - const AcceleratorMapping& entry = kAcceleratorMap[i]; - ui::AcceleratorGtk accelerator(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), ui::SCALE_FACTOR_100P, true); - canvas.DrawColor(color); - return new gfx::Image(gfx::ImageSkia(canvas.ExtractImageRep())); -} - -const gfx::Image* GetActiveBackgroundDefaultImage() { - static gfx::Image* image = NULL; - if (!image) - image = CreateImageForColor(kActiveBackgroundDefaultColor); - return image; -} - -const gfx::Image* GetInactiveBackgroundDefaultImage() { - static gfx::Image* image = NULL; - if (!image) - image = CreateImageForColor(kInactiveBackgroundDefaultColor); - return image; -} - -const gfx::Image* GetAttentionBackgroundDefaultImage() { - static gfx::Image* image = NULL; - if (!image) - image = CreateImageForColor(kAttentionBackgroundDefaultColor); - return image; -} - -const gfx::Image* GetMinimizeBackgroundDefaultImage() { - static gfx::Image* image = NULL; - if (!image) - 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& g_frame_size_ = *(new gfx::Size()); - -} // static NativePanel* Panel::CreateNativePanel(Panel* panel, const gfx::Rect& bounds) { - PanelGtk* panel_gtk = new PanelGtk(panel, bounds); - panel_gtk->Init(); - return panel_gtk; -} - -PanelGtk::PanelGtk(Panel* panel, const gfx::Rect& bounds) - : panel_(panel), - bounds_(bounds), - is_shown_(false), - paint_state_(PAINT_AS_INACTIVE), - is_drawing_attention_(false), - frame_cursor_(NULL), - is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), - window_(NULL), - window_container_(NULL), - window_vbox_(NULL), - render_area_event_box_(NULL), - contents_expanded_(NULL), - accel_group_(NULL) { -} - -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); - // Keep the window always on top. - gtk_window_set_keep_above(window_, TRUE); - // Show the window on all the virtual desktops. - gtk_window_stick(window_); - // Do not show an icon in the task bar. Window operations such as close, - // minimize etc. can only be done from the panel UI. - gtk_window_set_skip_taskbar_hint(window_, TRUE); - - // 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_, "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 browser 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_), 1, - 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(); -} - -void PanelGtk::UpdateWindowShape(int width, int height) { - // For panels, only top corners are rounded. The bottom corners are not - // rounded because panels are aligned to the bottom edge of the screen. - GdkRectangle top_top_rect = { 3, 0, width - 6, 1 }; - GdkRectangle top_mid_rect = { 1, 1, width - 2, 2 }; - GdkRectangle mid_rect = { 0, 3, width, height - 3 }; - GdkRegion* mask = gdk_region_rectangle(&top_top_rect); - gdk_region_union_with_rect(mask, &top_mid_rect); - 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; - - UpdateWindowShape(event->width, event->height); - configure_size_ = new_size; - - if (!g_frame_size_.IsEmpty()) - return FALSE; - - // Save the frame size allocated by the system after as the - // frame size will be affected when we shrink the panel smaller - // than the frame (e.g. when the panel is minimized). - g_frame_size_ = GetNonClientFrameSize(); - panel_->OnWindowSizeAvailable(); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PANEL_WINDOW_SIZE_KNOWN, - content::Source<Panel>(panel_.get()), - content::NotificationService::NoDetails()); - - return FALSE; -} - -void PanelGtk::ConnectAccelerators() { - accel_group_ = gtk_accel_group_new(); - gtk_window_add_accel_group(window_, accel_group_); - - const AcceleratorGtkMap& accelerator_table = GetAcceleratorTable(); - for (AcceleratorGtkMap::const_iterator iter = accelerator_table.begin(); - iter != accelerator_table.end(); ++iter) { - gtk_accel_group_connect( - accel_group_, - iter->first.GetGdkKeyCode(), - static_cast<GdkModifierType>(iter->first.modifiers()), - 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 AcceleratorGtkMap& accelerator_table = GetAcceleratorTable(); - for (AcceleratorGtkMap::const_iterator iter = accelerator_table.begin(); - iter != accelerator_table.end(); ++iter) { - gtk_accel_group_disconnect_key(accel_group_, - iter->first.GetGdkKeyCode(), - static_cast<GdkModifierType>(iter->first.modifiers())); - } - 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::UsingDefaultTheme() const { - // No theme is provided for attention painting. - if (paint_state_ == PAINT_FOR_ATTENTION) - return true; - - GtkThemeService* theme_provider = GtkThemeService::GetFrom(panel_->profile()); - return theme_provider->UsingDefaultTheme() || - theme_provider->UsingNativeTheme(); -} - -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; - - if (x < kFrameBorderThickness) { - // Left edge. - if (y < kResizeAreaCornerSize - kTopResizeAdjust) { - *edge = GDK_WINDOW_EDGE_NORTH_WEST; - } else if (y < bounds_.height() - kResizeAreaCornerSize) { - *edge = GDK_WINDOW_EDGE_WEST; - } else { - *edge = GDK_WINDOW_EDGE_SOUTH_WEST; - } - } else if (x < bounds_.width() - kFrameBorderThickness) { - if (y < kFrameBorderThickness - kTopResizeAdjust) { - // Top edge. - if (x < kResizeAreaCornerSize) { - *edge = GDK_WINDOW_EDGE_NORTH_WEST; - } else if (x < bounds_.width() - kResizeAreaCornerSize) { - *edge = GDK_WINDOW_EDGE_NORTH; - } else { - *edge = GDK_WINDOW_EDGE_NORTH_EAST; - } - } else if (y < bounds_.height() - kFrameBorderThickness) { - // Ignore the middle content area. - return false; - } else { - // Bottom edge. - if (x < kResizeAreaCornerSize) { - *edge = GDK_WINDOW_EDGE_SOUTH_WEST; - } else if (x < bounds_.width() - kResizeAreaCornerSize) { - *edge = GDK_WINDOW_EDGE_SOUTH; - } else { - *edge = GDK_WINDOW_EDGE_SOUTH_EAST; - } - } - } else { - // Right edge. - if (y < kResizeAreaCornerSize - kTopResizeAdjust) { - *edge = GDK_WINDOW_EDGE_NORTH_EAST; - } else if (y < bounds_.height() - kResizeAreaCornerSize) { - *edge = GDK_WINDOW_EDGE_EAST; - } else { - *edge = GDK_WINDOW_EDGE_SOUTH_EAST; - } - } - - // Special handling if bottom edge is not resizable. - if (panel::RESIZABLE_ALL_SIDES_EXCEPT_BOTTOM == resizability) { - if (*edge == GDK_WINDOW_EDGE_SOUTH) - return FALSE; - if (*edge == GDK_WINDOW_EDGE_SOUTH_WEST) - *edge = GDK_WINDOW_EDGE_WEST; - else if (*edge == GDK_WINDOW_EDGE_SOUTH_EAST) - *edge = GDK_WINDOW_EDGE_EAST; - } - - return true; -} - -const gfx::Image* PanelGtk::GetFrameBackground() const { - return UsingDefaultTheme() ? - GetDefaultFrameBackground() : GetThemedFrameBackground(); -} - -const gfx::Image* PanelGtk::GetDefaultFrameBackground() 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(); - } -} - -const gfx::Image* PanelGtk::GetThemedFrameBackground() const { - GtkThemeService* theme_provider = GtkThemeService::GetFrom(panel_->profile()); - return theme_provider->GetImageNamed(paint_state_ == PAINT_AS_ACTIVE ? - IDR_THEME_TOOLBAR : IDR_THEME_TAB_BACKGROUND); -} - -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 divider only if we're showing more than titlebar. - if (window_height > panel::kTitlebarHeight) { - cairo_set_source_rgb(cr, - SkColorGetR(kDividerColor) / 255.0, - SkColorGetG(kDividerColor) / 255.0, - SkColorGetB(kDividerColor) / 255.0); - cairo_rectangle(cr, 0, panel::kTitlebarHeight - 1, bounds_.width(), 1); - 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; - - 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 browser 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). - 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; - - // Grow the window from the botttom up to produce a 'reveal' animation. - int top = bounds_.bottom() - configure_size_.height(); - StartBoundsAnimation( - gfx::Rect(bounds_.x(), top, bounds_.width(), configure_size_.height()), - bounds_); -} - -gfx::Rect PanelGtk::GetPanelBounds() const { - return bounds_; -} - -void PanelGtk::SetPanelBounds(const gfx::Rect& bounds) { - SetBoundsInternal(bounds, true); -} - -void PanelGtk::SetPanelBoundsInstantly(const gfx::Rect& bounds) { - SetBoundsInternal(bounds, false); -} - -void PanelGtk::SetBoundsInternal(const gfx::Rect& bounds, bool animate) { - if (bounds == bounds_) - return; - - if (!animate) { - // If no animation is in progress, apply bounds change instantly. Otherwise, - // continue the animation with new target bounds. - if (!IsAnimatingBounds()) - gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(window_)), - bounds.x(), bounds.y(), - bounds.width(), bounds.height()); - } else if (is_shown_) { - StartBoundsAnimation(bounds_, bounds); - } - - bounds_ = bounds; -} - -void PanelGtk::ClosePanel() { - // We're already closing. Do nothing. - if (!window_) - return; - - if (!panel_->ShouldCloseWindow()) - return; - - if (bounds_animator_.get()) - bounds_animator_.reset(); - - 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_); -} - -void PanelGtk::DeactivatePanel() { - gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(window_))); - - // 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::GetNativePanelHandle() { - return window_; -} - -void PanelGtk::UpdatePanelTitleBar() { - TRACE_EVENT0("ui::gtk", "PanelGtk::UpdatePanelTitleBar"); - string16 title = panel_->GetWindowTitle(); - gtk_window_set_title(window_, UTF16ToUTF8(title).c_str()); - titlebar_->UpdateTitleAndIcon(); -} - -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()); -} - -FindBar* PanelGtk::CreatePanelFindBar() { - return NULL; // legacy -} - -void PanelGtk::NotifyPanelOnUserChangedTheme() { - titlebar_->UpdateTextColor(); - InvalidateWindow(); -} - -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_; -} - -bool PanelGtk::PreHandlePanelKeyboardEvent( - const NativeWebKeyboardEvent& event, - bool* is_keyboard_shortcut) { - // No need to prehandle as no keys are reserved. - return false; -} - -void PanelGtk::HandlePanelKeyboardEvent( - const NativeWebKeyboardEvent& event) { - GdkEventKey* os_event = &event.os_event->key; - if (os_event && event.type == WebKit::WebInputEvent::RawKeyDown) - gtk_window_activate_key(window_, os_event); -} - -void PanelGtk::FullScreenModeChanged(bool is_full_screen) { - // Nothing to do here as z-order rules for panels ensures that they're below - // any app running in full screen mode. -} - -void PanelGtk::PanelExpansionStateChanging( - Panel::ExpansionState old_state, Panel::ExpansionState new_state) { -} - -void PanelGtk::AttachWebContents(content::WebContents* contents) { - if (!contents) - return; - gfx::NativeView widget = contents->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->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); - } - } -} - -Browser* PanelGtk::GetPanelBrowser() const { - return NULL; // legacy -} - -gfx::Size PanelGtk::WindowSizeFromContentSize( - const gfx::Size& content_size) const { - return gfx::Size(content_size.width() + g_frame_size_.width(), - content_size.height() + g_frame_size_.height()); -} - -gfx::Size PanelGtk::ContentSizeFromWindowSize( - const gfx::Size& window_size) const { - return gfx::Size(window_size.width() - g_frame_size_.width(), - window_size.height() - g_frame_size_.height()); -} - -int PanelGtk::TitleOnlyHeight() const { - GtkAllocation allocation; - gtk_widget_get_allocation(titlebar_->widget(), &allocation); - return allocation.height; -} - -void PanelGtk::EnsurePanelFullyVisible() { - gtk_window_present(window_); -} - -void PanelGtk::SetPanelAlwaysOnTop(bool on_top) { - gtk_window_set_keep_above(window_, on_top); -} - -void PanelGtk::EnableResizeByMouse(bool enable) { -} - -void PanelGtk::UpdatePanelMinimizeRestoreButtonVisibility() { - titlebar_->UpdateMinimizeRestoreButtonVisibility(); -} - -void PanelGtk::StartBoundsAnimation( - const gfx::Rect& from_bounds, const gfx::Rect& to_bounds) { - animation_start_bounds_ = IsAnimatingBounds() ? - last_animation_progressed_bounds_ : from_bounds; - - bounds_animator_.reset(new PanelBoundsAnimation( - this, panel_.get(), animation_start_bounds_, to_bounds)); - - bounds_animator_->Start(); - last_animation_progressed_bounds_ = animation_start_bounds_; -} - -bool PanelGtk::IsAnimatingBounds() const { - return bounds_animator_.get() && bounds_animator_->is_animating(); -} - -void PanelGtk::AnimationEnded(const ui::Animation* animation) { - titlebar_->SendEnterNotifyToCloseButtonIfUnderMouse(); - panel_->manager()->OnPanelAnimationEnded(panel_.get()); -} - -void PanelGtk::AnimationProgressed(const ui::Animation* animation) { - DCHECK(is_shown_); - gfx::Rect new_bounds = bounds_animator_->CurrentValueBetween( - animation_start_bounds_, bounds_); - - gdk_window_move_resize(gtk_widget_get_window(GTK_WIDGET(window_)), - new_bounds.x(), new_bounds.y(), - new_bounds.width(), new_bounds.height()); - - last_animation_progressed_bounds_ = new_bounds; -} - -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 void WaitForWindowCreationToComplete() const OVERRIDE; - virtual bool IsWindowSizeKnown() const OVERRIDE; - virtual bool IsAnimatingBounds() const OVERRIDE; - virtual bool IsButtonVisible( - panel::TitlebarButtonType button_type) const 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) { - // If there is an animation, wait for it to finish as we don't handle button - // clicks while animation is in progress. - while (panel_gtk_->IsAnimatingBounds()) - MessageLoopForUI::current()->RunAllPending(); - - 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); - MessageLoopForUI::current()->RunAllPending(); -} - -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); - MessageLoopForUI::current()->RunAllPending(); -} - -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); - MessageLoopForUI::current()->RunAllPending(); -} - -void GtkNativePanelTesting::CancelDragTitlebar() { - if (!panel_gtk_->drag_helper_.get()) - return; - panel_gtk_->drag_helper_->OnGrabBrokenEvent(NULL, NULL); - MessageLoopForUI::current()->RunAllPending(); -} - -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) { - // TODO(jianli): to be implemented. http://crbug.com/102737 - return false; -} - -void GtkNativePanelTesting::WaitForWindowCreationToComplete() const { - while (g_frame_size_.IsEmpty()) - MessageLoopForUI::current()->RunAllPending(); - while (panel_gtk_->IsAnimatingBounds()) - MessageLoopForUI::current()->RunAllPending(); -} - -bool GtkNativePanelTesting::IsWindowSizeKnown() const { - return !g_frame_size_.IsEmpty(); -} - -bool GtkNativePanelTesting::IsAnimatingBounds() const { - return panel_gtk_->IsAnimatingBounds(); -} - -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()); + NOTIMPLEMENTED(); + return NULL; } diff --git a/chrome/browser/ui/panels/panel_gtk.h b/chrome/browser/ui/panels/panel_gtk.h deleted file mode 100644 index aa80666..0000000 --- a/chrome/browser/ui/panels/panel_gtk.h +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_PANELS_PANEL_GTK_H_ -#define CHROME_BROWSER_UI_PANELS_PANEL_GTK_H_ - -#include <gtk/gtk.h> -#include <map> - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/timer.h" -#include "chrome/browser/ui/panels/native_panel.h" -#include "ui/base/animation/animation_delegate.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/base/x/active_window_watcher_x_observer.h" -#include "ui/gfx/rect.h" - -class Panel; -class PanelBoundsAnimation; -class PanelTitlebarGtk; -class PanelDragGtk; -class GtkNativePanelTesting; - -namespace gfx { -class Image; -} - -// An implementation of the native panel in GTK. -class PanelGtk : public NativePanel, - public ui::ActiveWindowWatcherXObserver, - public ui::AnimationDelegate { - public: - enum PaintState { - PAINT_AS_ACTIVE, - PAINT_AS_INACTIVE, - PAINT_AS_MINIMIZED, - PAINT_FOR_ATTENTION - }; - - PanelGtk(Panel* panel, const gfx::Rect& bounds); - virtual ~PanelGtk(); - - void Init(); - - // Overridden from NativePanel. - virtual void ShowPanel() OVERRIDE; - virtual void ShowPanelInactive() OVERRIDE; - virtual gfx::Rect GetPanelBounds() const OVERRIDE; - virtual void SetPanelBounds(const gfx::Rect& bounds) OVERRIDE; - virtual void SetPanelBoundsInstantly(const gfx::Rect& bounds) OVERRIDE; - virtual void ClosePanel() OVERRIDE; - virtual void ActivatePanel() OVERRIDE; - virtual void DeactivatePanel() OVERRIDE; - virtual bool IsPanelActive() const OVERRIDE; - virtual void PreventActivationByOS(bool prevent_activation) OVERRIDE; - virtual gfx::NativeWindow GetNativePanelHandle() OVERRIDE; - virtual void UpdatePanelTitleBar() OVERRIDE; - virtual void UpdatePanelLoadingAnimations(bool should_animate) OVERRIDE; - virtual FindBar* CreatePanelFindBar() OVERRIDE; - virtual void NotifyPanelOnUserChangedTheme() OVERRIDE; - virtual void PanelCut() OVERRIDE; - virtual void PanelCopy() OVERRIDE; - virtual void PanelPaste() OVERRIDE; - virtual void DrawAttention(bool draw_attention) OVERRIDE; - virtual bool IsDrawingAttention() const OVERRIDE; - virtual bool PreHandlePanelKeyboardEvent( - const content::NativeWebKeyboardEvent& event, - bool* is_keyboard_shortcut) OVERRIDE; - virtual void HandlePanelKeyboardEvent( - const content::NativeWebKeyboardEvent& event) OVERRIDE; - virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE; - virtual void PanelExpansionStateChanging( - Panel::ExpansionState old_state, - Panel::ExpansionState new_state) OVERRIDE; - virtual void AttachWebContents(content::WebContents* contents) OVERRIDE; - virtual void DetachWebContents(content::WebContents* contents) OVERRIDE; - virtual Browser* GetPanelBrowser() const OVERRIDE; - // These sizes are in screen coordinates. - virtual gfx::Size WindowSizeFromContentSize( - const gfx::Size& content_size) const OVERRIDE; - virtual gfx::Size ContentSizeFromWindowSize( - const gfx::Size& window_size) const OVERRIDE; - virtual int TitleOnlyHeight() const OVERRIDE; - virtual void EnsurePanelFullyVisible() OVERRIDE; - virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE; - virtual void EnableResizeByMouse(bool enable) OVERRIDE; - virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE; - - virtual NativePanelTesting* CreateNativePanelTesting() OVERRIDE; - - // Overridden from ActiveWindowWatcherXObserver. - virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; - - bool UsingDefaultTheme() const; - - Panel* panel() const { return panel_.get(); } - PaintState paint_state() const { return paint_state_; } - PanelTitlebarGtk* titlebar() const { return titlebar_.get(); } - - private: - friend class GtkNativePanelTesting; - - // Applies our custom window shape with rounded top corners. - void UpdateWindowShape(int width, int height); - - // Checks to see if the mouse pointer at |x|, |y| is over the border of the - // custom frame (a spot that should trigger a window resize). Returns true if - // it should and sets |edge|. - bool GetWindowEdge(int x, int y, GdkWindowEdge* edge) const; - - // Connect/disconnect accelerators for keyboard shortcut support. - void ConnectAccelerators(); - void DisconnectAccelerators(); - - // Returns the image to paint the frame. - const gfx::Image* GetFrameBackground() const; - const gfx::Image* GetDefaultFrameBackground() const; - const gfx::Image* GetThemedFrameBackground() const; - - // Animation when panel is first shown. - void RevealPanel(); - - void StartBoundsAnimation(const gfx::Rect& from_bounds, - const gfx::Rect& to_bounds); - bool IsAnimatingBounds() const; - - // Overridden from AnimationDelegate: - virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE; - virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; - - // Creates helper for handling drags if not already created. - void EnsureDragHelperCreated(); - - void SetBoundsInternal(const gfx::Rect& bounds, bool animate); - - void LoadingAnimationCallback(); - - // Returns the size of the window frame around the client content area. - gfx::Size GetNonClientFrameSize() const; - - // Invalidate window to force repaint. - void InvalidateWindow(); - - // Callback for accelerator activation. |user_data| stores the command id - // of the matched accelerator. - static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group, - GObject* acceleratable, - guint keyval, - GdkModifierType modifier, - void* user_data); - - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMainWindowDeleteEvent, - GdkEvent*); - CHROMEGTK_CALLBACK_0(PanelGtk, void, OnMainWindowDestroy); - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnConfigure, GdkEventConfigure*); - // Callback for when the custom frame alignment needs to be redrawn. - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnCustomFrameExpose, - GdkEventExpose*); - // Key press event callback. - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnKeyPress, GdkEventKey*); - // Mouse move and button press callbacks. If mouse hits titlebar, - // the titlebar gets the event, else the window gets the button press. - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMouseMoveEvent, - GdkEventMotion*); - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnButtonPressEvent, - GdkEventButton*); - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, - OnTitlebarButtonPressEvent, GdkEventButton*); - CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, - OnTitlebarButtonReleaseEvent, GdkEventButton*); - - scoped_ptr<Panel> panel_; - gfx::Rect bounds_; - - // True after panel has been shown. - bool is_shown_; - - scoped_ptr<PanelDragGtk> drag_helper_; - - // The configure size of the current window, used to figure out whether to - // ignore later configure events. See OnConfigure() for more information. - gfx::Size configure_size_; - - // Indicates different painting state, active, drawing attention or else. - PaintState paint_state_; - - // Indicates that the panel is currently drawing attention. - bool is_drawing_attention_; - - // Used to animate the bounds change. - scoped_ptr<PanelBoundsAnimation> bounds_animator_; - gfx::Rect animation_start_bounds_; - - // This records the bounds set on the last animation progress notification. - // We need this for the case where a new bounds animation starts before the - // current one completes. In this case, we want to start the new animation - // from where the last one left. - gfx::Rect last_animation_progressed_bounds_; - - // The timer used to update frames for the Loading Animation. - base::RepeatingTimer<PanelGtk> loading_animation_timer_; - - // The current window cursor. We set it to a resize cursor when over the - // custom frame border. We set it to NULL if we want the default cursor. - GdkCursor* frame_cursor_; - - // True if the window manager thinks the window is active. Not all window - // managers keep track of this state (_NET_ACTIVE_WINDOW), in which case - // this will always be true. - bool is_active_; - - // Top level window. - GtkWindow* window_; - // GtkAlignment that holds the interior components of the chromium window. - // This is used to draw the custom frame border and content shadow. - GtkWidget* window_container_; - // VBox that holds everything (titlebar, web contents). - GtkWidget* window_vbox_; - // EventBox that holds web contents. - GtkWidget* render_area_event_box_; - // We insert and remove WebContents GtkWidgets into this expanded. - GtkWidget* contents_expanded_; - - // The accelerator group used to handle accelerators, owned by this object. - GtkAccelGroup* accel_group_; - - // The container for the titlebar. - scoped_ptr<PanelTitlebarGtk> titlebar_; - - DISALLOW_COPY_AND_ASSIGN(PanelGtk); -}; - -#endif // CHROME_BROWSER_UI_PANELS_PANEL_GTK_H_ diff --git a/chrome/browser/ui/panels/panel_host.cc b/chrome/browser/ui/panels/panel_host.cc index 3b425c4..a4ec274 100644 --- a/chrome/browser/ui/panels/panel_host.cc +++ b/chrome/browser/ui/panels/panel_host.cc @@ -11,7 +11,6 @@ #include "chrome/browser/favicon/favicon_tab_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/panels/panel.h" -#include "chrome/browser/ui/prefs/prefs_tab_helper.h" #include "chrome/browser/view_type_utils.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/extensions/extension_messages.h" @@ -54,16 +53,14 @@ void PanelHost::Init(const GURL& url) { content::WebContentsObserver::Observe(web_contents_.get()); favicon_tab_helper_.reset(new FaviconTabHelper(web_contents_.get())); - prefs_tab_helper_.reset(new PrefsTabHelper(web_contents_.get())); web_contents_->GetController().LoadURL( url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); } void PanelHost::DestroyWebContents() { - favicon_tab_helper_.reset(); - prefs_tab_helper_.reset(); web_contents_.reset(); + favicon_tab_helper_.reset(); } SkBitmap PanelHost::GetPageIcon() const { diff --git a/chrome/browser/ui/panels/panel_host.h b/chrome/browser/ui/panels/panel_host.h index f2732c2..fa68c3d 100644 --- a/chrome/browser/ui/panels/panel_host.h +++ b/chrome/browser/ui/panels/panel_host.h @@ -15,7 +15,6 @@ class FaviconTabHelper; class GURL; class Panel; -class PrefsTabHelper; class Profile; namespace content { @@ -99,7 +98,6 @@ class PanelHost : public content::WebContentsDelegate, // The following factory is used to close the panel via the message loop. base::WeakPtrFactory<PanelHost> weak_factory_; - scoped_ptr<PrefsTabHelper> prefs_tab_helper_; scoped_ptr<FaviconTabHelper> favicon_tab_helper_; scoped_ptr<content::WebContents> web_contents_; diff --git a/chrome/browser/ui/panels/panel_resize_browsertest.cc b/chrome/browser/ui/panels/panel_resize_browsertest.cc index 7ca7ea3..41c026e 100644 --- a/chrome/browser/ui/panels/panel_resize_browsertest.cc +++ b/chrome/browser/ui/panels/panel_resize_browsertest.cc @@ -8,6 +8,9 @@ #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_resize_controller.h" +// Refactor has only been done for Win and Mac panels so far. +#if defined(OS_WIN) || defined(OS_MACOSX) + class PanelResizeBrowserTest : public BasePanelBrowserTest { public: PanelResizeBrowserTest() : BasePanelBrowserTest() { @@ -410,3 +413,5 @@ IN_PROC_BROWSER_TEST_F(PanelResizeBrowserTest, ResizeDetachedPanelToTop) { panel_manager->CloseAll(); } + +#endif // OS_WIN || OS_MACOSX diff --git a/chrome/browser/ui/panels/panel_titlebar_gtk.cc b/chrome/browser/ui/panels/panel_titlebar_gtk.cc deleted file mode 100644 index e15f9c6..0000000 --- a/chrome/browser/ui/panels/panel_titlebar_gtk.cc +++ /dev/null @@ -1,311 +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/panels/panel_titlebar_gtk.h" - -#include "base/utf_string_conversions.h" -#include "chrome/browser/ui/gtk/custom_button.h" -#include "chrome/browser/ui/gtk/gtk_theme_service.h" -#include "chrome/browser/ui/gtk/gtk_util.h" -#include "chrome/browser/ui/panels/panel.h" -#include "chrome/browser/ui/panels/panel_gtk.h" -#include "content/public/browser/web_contents.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "ui/base/gtk/gtk_compat.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/skia_utils_gtk.h" - -namespace { - -// Padding around the titlebar. -const int kPanelTitlebarPaddingTop = 7; -const int kPanelTitlebarPaddingBottom = 7; -const int kPanelTitlebarPaddingLeft = 4; -const int kPanelTitlebarPaddingRight = 8; - -// Spacing between buttons of panel's titlebar. -const int kPanelButtonSpacing = 5; - -// Spacing between the icon and the title text. -const int kPanelIconTitleSpacing = 9; - -// Color used to draw title text under default theme. -const SkColor kTitleTextDefaultColor = SkColorSetRGB(0xf9, 0xf9, 0xf9); - -// Markup used to paint the title with the desired font. -const char* const kTitleMarkupPrefix = "<span face='Arial' size='11264'>"; -const char* const kTitleMarkupSuffix = "</span>"; - -} // namespace - -PanelTitlebarGtk::PanelTitlebarGtk(PanelGtk* panel_gtk) - : panel_gtk_(panel_gtk), - container_(NULL), - titlebar_right_buttons_vbox_(NULL), - titlebar_right_buttons_hbox_(NULL), - icon_(NULL), - title_(NULL), - theme_service_(GtkThemeService::GetFrom(panel_gtk_->panel()->profile())) { -} - -PanelTitlebarGtk::~PanelTitlebarGtk() { -} - -void PanelTitlebarGtk::Init() { - container_ = gtk_event_box_new(); - gtk_widget_set_name(container_, "chrome-panel-titlebar"); - gtk_event_box_set_visible_window(GTK_EVENT_BOX(container_), FALSE); - - // We use an alignment to control the titlebar paddings. - GtkWidget* container_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); - gtk_container_add(GTK_CONTAINER(container_), container_alignment); - gtk_alignment_set_padding(GTK_ALIGNMENT(container_alignment), - kPanelTitlebarPaddingTop, - kPanelTitlebarPaddingBottom, - kPanelTitlebarPaddingLeft, - kPanelTitlebarPaddingRight); - - // Add a container box. - GtkWidget* container_hbox = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(container_alignment), container_hbox); - - // Add minimize/restore and close buttons. Panel buttons are always placed - // on the right part of the titlebar. - titlebar_right_buttons_vbox_ = gtk_vbox_new(FALSE, 0); - gtk_box_pack_end(GTK_BOX(container_hbox), titlebar_right_buttons_vbox_, - FALSE, FALSE, 0); - BuildButtons(); - - // Add hbox for holding icon and title. - GtkWidget* icon_title_hbox = gtk_hbox_new(FALSE, kPanelIconTitleSpacing); - gtk_box_pack_start(GTK_BOX(container_hbox), icon_title_hbox, TRUE, TRUE, 0); - - // Add icon. We use the app logo as a placeholder image so the title doesn't - // jump around. - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - icon_ = gtk_image_new_from_pixbuf(rb.GetNativeImageNamed( - IDR_PRODUCT_LOGO_16, ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf()); - g_object_set_data(G_OBJECT(icon_), "left-align-popup", - reinterpret_cast<void*>(true)); - gtk_box_pack_start(GTK_BOX(icon_title_hbox), icon_, FALSE, FALSE, 0); - - // Add title. - title_ = gtk_label_new(NULL); - gtk_label_set_ellipsize(GTK_LABEL(title_), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment(GTK_MISC(title_), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(icon_title_hbox), title_, TRUE, TRUE, 0); - UpdateTitleAndIcon(); - UpdateTextColor(); - - gtk_widget_show_all(container_); -} - -SkColor PanelTitlebarGtk::GetTextColor() const { - if (panel_gtk_->UsingDefaultTheme()) - return kTitleTextDefaultColor; - return theme_service_->GetColor(panel_gtk_->paint_state() == - PanelGtk::PAINT_AS_ACTIVE ? - ThemeService::COLOR_TAB_TEXT : - ThemeService::COLOR_BACKGROUND_TAB_TEXT); -} - -void PanelTitlebarGtk::BuildButtons() { - minimize_button_.reset(CreateButton(panel::MINIMIZE_BUTTON)); - restore_button_.reset(CreateButton(panel::RESTORE_BUTTON)); - close_button_.reset(CreateButton(panel::CLOSE_BUTTON)); - - // We control visibility of minimize and restore buttons. - gtk_widget_set_no_show_all(minimize_button_->widget(), TRUE); - gtk_widget_set_no_show_all(restore_button_->widget(), TRUE); - - // Now show the correct widgets in the two hierarchies. - UpdateMinimizeRestoreButtonVisibility(); -} - -CustomDrawButton* PanelTitlebarGtk::CreateButton( - panel::TitlebarButtonType button_type) { - int normal_image_id = -1; - int pressed_image_id = -1; - int hover_image_id = -1; - int tooltip_id = -1; - GetButtonResources(button_type, &normal_image_id, &pressed_image_id, - &hover_image_id, &tooltip_id); - - CustomDrawButton* button = new CustomDrawButton(normal_image_id, - pressed_image_id, - hover_image_id, - 0); - gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK); - g_signal_connect(button->widget(), "clicked", - G_CALLBACK(OnButtonClickedThunk), this); - - std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip_id); - gtk_widget_set_tooltip_text(button->widget(), - localized_tooltip.c_str()); - - GtkWidget* box = GetButtonHBox(); - gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0); - return button; -} - -void PanelTitlebarGtk::GetButtonResources( - panel::TitlebarButtonType button_type, - int* normal_image_id, - int* pressed_image_id, - int* hover_image_id, - int* tooltip_id) const { - switch (button_type) { - case panel::CLOSE_BUTTON: - *normal_image_id = IDR_PANEL_CLOSE; - *pressed_image_id = IDR_PANEL_CLOSE_C; - *hover_image_id = IDR_PANEL_CLOSE_H; - *tooltip_id = IDS_PANEL_CLOSE_TOOLTIP; - break; - case panel::MINIMIZE_BUTTON: - *normal_image_id = IDR_PANEL_MINIMIZE; - *pressed_image_id = IDR_PANEL_MINIMIZE_C; - *hover_image_id = IDR_PANEL_MINIMIZE_H; - *tooltip_id = IDS_PANEL_MINIMIZE_TOOLTIP; - break; - case panel::RESTORE_BUTTON: - *normal_image_id = IDR_PANEL_RESTORE; - *pressed_image_id = IDR_PANEL_RESTORE_C; - *hover_image_id = IDR_PANEL_RESTORE_H; - *tooltip_id = IDS_PANEL_RESTORE_TOOLTIP; - break; - } -} - -GtkWidget* PanelTitlebarGtk::GetButtonHBox() { - if (!titlebar_right_buttons_hbox_) { - // We put the minimize/restore/close buttons in a vbox so they are top - // aligned (up to padding) and don't vertically stretch. - titlebar_right_buttons_hbox_ = gtk_hbox_new(FALSE, kPanelButtonSpacing); - gtk_box_pack_start(GTK_BOX(titlebar_right_buttons_vbox_), - titlebar_right_buttons_hbox_, FALSE, FALSE, 0); - } - - return titlebar_right_buttons_hbox_; -} - -void PanelTitlebarGtk::UpdateTitleAndIcon() { - std::string title_text = - UTF16ToUTF8(panel_gtk_->panel()->GetWindowTitle()); - - // Add the markup to show the title in the desired font. - gchar* escaped_title_text = g_markup_escape_text(title_text.c_str(), -1); - gchar* title_text_with_markup = g_strconcat(kTitleMarkupPrefix, - escaped_title_text, - kTitleMarkupSuffix, - NULL); - gtk_label_set_markup(GTK_LABEL(title_), title_text_with_markup); - g_free(escaped_title_text); - g_free(title_text_with_markup); -} - -void PanelTitlebarGtk::UpdateThrobber( - content::WebContents* web_contents) { - if (web_contents && web_contents->IsLoading()) { - GdkPixbuf* icon_pixbuf = - throbber_.GetNextFrame(web_contents->IsWaitingForResponse()); - gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon_pixbuf); - } else { - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); - - SkBitmap icon = panel_gtk_->panel()->GetCurrentPageIcon(); - if (icon.empty()) { - // Fallback to the Chromium icon if the page has no icon. - gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), - rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf()); - } else { - GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(icon); - gtk_image_set_from_pixbuf(GTK_IMAGE(icon_), icon_pixbuf); - g_object_unref(icon_pixbuf); - } - - throbber_.Reset(); - } -} - -void PanelTitlebarGtk::UpdateTextColor() { - GdkColor text_color = gfx::SkColorToGdkColor(GetTextColor()); - gtk_util::SetLabelColor(title_, &text_color); -} - -void PanelTitlebarGtk::UpdateMinimizeRestoreButtonVisibility() { - Panel* panel = panel_gtk_->panel(); - gtk_widget_set_visible(minimize_button_->widget(), panel->CanMinimize()); - gtk_widget_set_visible(restore_button_->widget(), panel->CanRestore()); -} - -void PanelTitlebarGtk::OnButtonClicked(GtkWidget* button) { - Panel* panel = panel_gtk_->panel(); - if (close_button_->widget() == button) { - panel->Close(); - return; - } - - GdkEvent* event = gtk_get_current_event(); - DCHECK(event && event->type == GDK_BUTTON_RELEASE); - - if (minimize_button_->widget() == button) { - panel->OnMinimizeButtonClicked( - (event->button.state & GDK_CONTROL_MASK) ? - panel::APPLY_TO_ALL : panel::NO_MODIFIER); - } else if (restore_button_->widget() == button) { - panel->OnRestoreButtonClicked( - (event->button.state & GDK_CONTROL_MASK) ? - panel::APPLY_TO_ALL : panel::NO_MODIFIER); - } - - gdk_event_free(event); -} - -void PanelTitlebarGtk::SendEnterNotifyToCloseButtonIfUnderMouse() { - if (!close_button()) - return; - - gint x; - gint y; - GtkAllocation widget_allocation = close_button()->WidgetAllocation(); - gtk_widget_get_pointer(GTK_WIDGET(close_button()->widget()), &x, &y); - - gfx::Rect button_rect(0, 0, widget_allocation.width, - widget_allocation.height); - if (!button_rect.Contains(x, y)) { - // Mouse is not over the close button. - return; - } - - // Create and emit an enter-notify-event on close button. - GValue return_value; - return_value.g_type = G_TYPE_BOOLEAN; - g_value_set_boolean(&return_value, false); - - GdkEvent* event = gdk_event_new(GDK_ENTER_NOTIFY); - event->crossing.window = - gtk_button_get_event_window(GTK_BUTTON(close_button()->widget())); - event->crossing.send_event = FALSE; - event->crossing.subwindow = gtk_widget_get_window(close_button()->widget()); - event->crossing.time = gtk_util::XTimeNow(); - event->crossing.x = x; - event->crossing.y = y; - event->crossing.x_root = widget_allocation.x; - event->crossing.y_root = widget_allocation.y; - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_ANCESTOR; - event->crossing.focus = true; - event->crossing.state = 0; - - g_signal_emit_by_name(GTK_OBJECT(close_button()->widget()), - "enter-notify-event", event, - &return_value); -} - -GtkWidget* PanelTitlebarGtk::widget() const { - return container_; -} diff --git a/chrome/browser/ui/panels/panel_titlebar_gtk.h b/chrome/browser/ui/panels/panel_titlebar_gtk.h deleted file mode 100644 index ddfa452..0000000 --- a/chrome/browser/ui/panels/panel_titlebar_gtk.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_PANELS_PANEL_TITLEBAR_GTK_H_ -#define CHROME_BROWSER_UI_PANELS_PANEL_TITLEBAR_GTK_H_ - -#include <gtk/gtk.h> - -#include "base/compiler_specific.h" -#include "base/memory/scoped_ptr.h" -#include "chrome/browser/ui/gtk/titlebar_throb_animation.h" -#include "chrome/browser/ui/panels/panel_constants.h" -#include "ui/base/gtk/gtk_signal.h" -#include "ui/gfx/skia_util.h" - -class CustomDrawButton; -class GtkThemeService; -class PanelGtk; - -namespace content { -class WebContents; -} - -class PanelTitlebarGtk { - public: - explicit PanelTitlebarGtk(PanelGtk* panel_gtk); - virtual ~PanelTitlebarGtk(); - - void UpdateTextColor(); - void UpdateMinimizeRestoreButtonVisibility(); - - // When a panel appears in the same position as the one of the panel being - // closed and the cursor stays in the close button, the close button appears - // not to be clickable. This is because neither "enter-notify-event" nor - // "clicked" event for the new panel gets fired if the mouse does not move. - // This creates a bad experience when a user has multiple panels of the same - // size (which is typical) and tries closing them all by repeatedly clicking - // in the same place on the screen. - // - // Opened a gtk bug for this - - // https://bugzilla.gnome.org/show_bug.cgi?id=667841 - void SendEnterNotifyToCloseButtonIfUnderMouse(); - - void Init(); - void UpdateTitleAndIcon(); - void UpdateThrobber(content::WebContents* web_contents); - GtkWidget* widget() const; - - private: - friend class GtkNativePanelTesting; - - void BuildButtons(); - CustomDrawButton* CreateButton(panel::TitlebarButtonType button_type); - void GetButtonResources(panel::TitlebarButtonType button_type, - int* normal_image_id, - int* pressed_image_id, - int* hover_image_id, - int* tooltip_id) const; - GtkWidget* GetButtonHBox(); - - // Callback for minimize/restore/close buttons. - CHROMEGTK_CALLBACK_0(PanelTitlebarGtk, void, OnButtonClicked); - - CustomDrawButton* close_button() const { return close_button_.get(); } - CustomDrawButton* minimize_button() const { return minimize_button_.get(); } - CustomDrawButton* restore_button() const { return restore_button_.get(); } - - SkColor GetTextColor() const; - - // Pointers to the native panel window that owns us and its GtkWindow. - PanelGtk* panel_gtk_; - - // The container widget the holds the hbox which contains the whole titlebar. - GtkWidget* container_; - - // VBoxes that holds the minimize/restore/close buttons box. - GtkWidget* titlebar_right_buttons_vbox_; - - // HBoxes that contains the actual min/max/close buttons. - GtkWidget* titlebar_right_buttons_hbox_; - - // The icon and page title. - GtkWidget* icon_; - GtkWidget* title_; - - // The buttons. - scoped_ptr<CustomDrawButton> close_button_; - scoped_ptr<CustomDrawButton> minimize_button_; - scoped_ptr<CustomDrawButton> restore_button_; - - TitlebarThrobAnimation throbber_; - GtkThemeService* theme_service_; - - DISALLOW_COPY_AND_ASSIGN(PanelTitlebarGtk); -}; - -#endif // CHROME_BROWSER_UI_PANELS_PANEL_TITLEBAR_GTK_H_ |