1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_ 6 #define CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_ 7 8 #include <gtk/gtk.h> 9 #include <map> 10 11 #include "base/basictypes.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/timer/timer.h" 14 #include "chrome/browser/ui/panels/native_panel.h" 15 #include "chrome/browser/ui/panels/panel_constants.h" 16 #include "ui/base/gtk/gtk_signal.h" 17 #include "ui/base/x/active_window_watcher_x_observer.h" 18 #include "ui/gfx/rect.h" 19 20 class Panel; 21 class PanelTitlebarGtk; 22 class PanelDragGtk; 23 class GtkNativePanelTesting; 24 25 namespace gfx { 26 class Image; 27 } 28 29 // An implementation of the native panel in GTK. 30 class PanelGtk : public NativePanel, 31 public ui::ActiveWindowWatcherXObserver { 32 public: 33 enum PaintState { 34 PAINT_AS_ACTIVE, 35 PAINT_AS_INACTIVE, 36 PAINT_AS_MINIMIZED, 37 PAINT_FOR_ATTENTION 38 }; 39 40 PanelGtk(Panel* panel, const gfx::Rect& bounds, bool always_on_top); 41 virtual ~PanelGtk(); 42 43 void Init(); 44 45 // Overridden from NativePanel. 46 virtual void ShowPanel() OVERRIDE; 47 virtual void ShowPanelInactive() OVERRIDE; 48 virtual gfx::Rect GetPanelBounds() const OVERRIDE; 49 virtual void SetPanelBounds(const gfx::Rect& bounds) OVERRIDE; 50 virtual void SetPanelBoundsInstantly(const gfx::Rect& bounds) OVERRIDE; 51 virtual void ClosePanel() OVERRIDE; 52 virtual void ActivatePanel() OVERRIDE; 53 virtual void DeactivatePanel() OVERRIDE; 54 virtual bool IsPanelActive() const OVERRIDE; 55 virtual void PreventActivationByOS(bool prevent_activation) OVERRIDE; 56 virtual gfx::NativeWindow GetNativePanelWindow() OVERRIDE; 57 virtual void UpdatePanelTitleBar() OVERRIDE; 58 virtual void UpdatePanelLoadingAnimations(bool should_animate) OVERRIDE; 59 virtual void PanelWebContentsFocused(content::WebContents* contents) OVERRIDE; 60 virtual void PanelCut() OVERRIDE; 61 virtual void PanelCopy() OVERRIDE; 62 virtual void PanelPaste() OVERRIDE; 63 virtual void DrawAttention(bool draw_attention) OVERRIDE; 64 virtual bool IsDrawingAttention() const OVERRIDE; 65 virtual void HandlePanelKeyboardEvent( 66 const content::NativeWebKeyboardEvent& event) OVERRIDE; 67 virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE; 68 virtual void PanelExpansionStateChanging( 69 Panel::ExpansionState old_state, 70 Panel::ExpansionState new_state) OVERRIDE; 71 virtual void AttachWebContents(content::WebContents* contents) OVERRIDE; 72 virtual void DetachWebContents(content::WebContents* contents) OVERRIDE; 73 // These sizes are in screen coordinates. 74 virtual gfx::Size WindowSizeFromContentSize( 75 const gfx::Size& content_size) const OVERRIDE; 76 virtual gfx::Size ContentSizeFromWindowSize( 77 const gfx::Size& window_size) const OVERRIDE; 78 virtual int TitleOnlyHeight() const OVERRIDE; 79 virtual bool IsPanelAlwaysOnTop() const OVERRIDE; 80 virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE; 81 virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE; 82 virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE; 83 virtual void MinimizePanelBySystem() OVERRIDE; 84 virtual bool IsPanelMinimizedBySystem() const OVERRIDE; 85 virtual bool IsPanelShownOnActiveDesktop() const OVERRIDE; 86 virtual void ShowShadow(bool show) OVERRIDE; 87 88 virtual NativePanelTesting* CreateNativePanelTesting() OVERRIDE; 89 90 // Overridden from ActiveWindowWatcherXObserver. 91 virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; 92 panel()93 Panel* panel() const { return panel_.get(); } paint_state()94 PaintState paint_state() const { return paint_state_; } titlebar()95 PanelTitlebarGtk* titlebar() const { return titlebar_.get(); } 96 97 private: 98 friend class GtkNativePanelTesting; 99 100 // Applies our custom window shape with rounded or non-rounded corners. 101 void UpdateWindowShape(); 102 103 // Checks to see if the mouse pointer at |x|, |y| is over the border of the 104 // custom frame (a spot that should trigger a window resize). Returns true if 105 // it should and sets |edge|. 106 bool GetWindowEdge(int x, int y, GdkWindowEdge* edge) const; 107 108 // Connect/disconnect accelerators for keyboard shortcut support. 109 void ConnectAccelerators(); 110 void DisconnectAccelerators(); 111 112 // Returns the image to paint the frame. 113 gfx::Image GetFrameBackground() const; 114 115 // Animation when panel is first shown. 116 void RevealPanel(); 117 118 // Creates helper for handling drags if not already created. 119 void EnsureDragHelperCreated(); 120 121 void SetBoundsInternal(const gfx::Rect& bounds); 122 123 void LoadingAnimationCallback(); 124 125 // Returns the size of the window frame around the client content area. 126 gfx::Size GetNonClientFrameSize() const; 127 128 // Invalidate window to force repaint. 129 void InvalidateWindow(); 130 131 // Callback for accelerator activation. |user_data| stores the command id 132 // of the matched accelerator. 133 static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group, 134 GObject* acceleratable, 135 guint keyval, 136 GdkModifierType modifier, 137 void* user_data); 138 139 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMainWindowDeleteEvent, 140 GdkEvent*); 141 CHROMEGTK_CALLBACK_0(PanelGtk, void, OnMainWindowDestroy); 142 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnConfigure, GdkEventConfigure*); 143 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnWindowState, GdkEventWindowState*); 144 // Callback for when the custom frame alignment needs to be redrawn. 145 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnCustomFrameExpose, 146 GdkEventExpose*); 147 // Key press event callback. 148 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnKeyPress, GdkEventKey*); 149 // Mouse move and button press callbacks. If mouse hits titlebar, 150 // the titlebar gets the event, else the window gets the button press. 151 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMouseMoveEvent, 152 GdkEventMotion*); 153 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnButtonPressEvent, 154 GdkEventButton*); 155 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, 156 OnTitlebarButtonPressEvent, GdkEventButton*); 157 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, 158 OnTitlebarButtonReleaseEvent, GdkEventButton*); 159 160 scoped_ptr<Panel> panel_; 161 gfx::Rect bounds_; 162 163 // True if the panel should always stay on top of other windows. 164 bool always_on_top_; 165 166 // True after panel has been shown. 167 bool is_shown_; 168 169 scoped_ptr<PanelDragGtk> drag_helper_; 170 171 // The configure size of the current window, used to figure out whether to 172 // ignore later configure events. See OnConfigure() for more information. 173 gfx::Size configure_size_; 174 175 // Indicates different painting state, active, drawing attention or else. 176 PaintState paint_state_; 177 178 // Indicates that the panel is currently drawing attention. 179 bool is_drawing_attention_; 180 181 // The timer used to update frames for the Loading Animation. 182 base::RepeatingTimer<PanelGtk> loading_animation_timer_; 183 184 // The current window cursor. We set it to a resize cursor when over the 185 // custom frame border. We set it to NULL if we want the default cursor. 186 GdkCursor* frame_cursor_; 187 188 // True if the window manager thinks the window is active. Not all window 189 // managers keep track of this state (_NET_ACTIVE_WINDOW), in which case 190 // this will always be true. 191 bool is_active_; 192 193 // True if the window manager thinks the window is minimized (iconified). 194 // Not all window managers support this, in which case this will always be 195 // false. 196 bool is_minimized_; 197 198 // Top level window. 199 GtkWindow* window_; 200 // GtkAlignment that holds the interior components of the chromium window. 201 // This is used to draw the custom frame border and content shadow. 202 GtkWidget* window_container_; 203 // VBox that holds everything (titlebar, web contents). 204 GtkWidget* window_vbox_; 205 // EventBox that holds web contents. 206 GtkWidget* render_area_event_box_; 207 // We insert and remove WebContents GtkWidgets into this expanded. 208 GtkWidget* contents_expanded_; 209 210 // The accelerator group used to handle accelerators, owned by this object. 211 GtkAccelGroup* accel_group_; 212 213 // The container for the titlebar. 214 scoped_ptr<PanelTitlebarGtk> titlebar_; 215 216 // Indicates how the window corner should be rendered, rounded or not. 217 panel::CornerStyle corner_style_; 218 219 DISALLOW_COPY_AND_ASSIGN(PanelGtk); 220 }; 221 222 #endif // CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_ 223