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 EnableResizeByMouse(bool enable) OVERRIDE; 82 virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE; 83 virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE; 84 virtual void MinimizePanelBySystem() OVERRIDE; 85 virtual bool IsPanelMinimizedBySystem() const OVERRIDE; 86 virtual bool IsPanelShownOnActiveDesktop() const OVERRIDE; 87 virtual void ShowShadow(bool show) OVERRIDE; 88 89 virtual NativePanelTesting* CreateNativePanelTesting() OVERRIDE; 90 91 // Overridden from ActiveWindowWatcherXObserver. 92 virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; 93 94 Panel* panel() const { return panel_.get(); } 95 PaintState paint_state() const { return paint_state_; } 96 PanelTitlebarGtk* titlebar() const { return titlebar_.get(); } 97 98 private: 99 friend class GtkNativePanelTesting; 100 101 // Applies our custom window shape with rounded or non-rounded corners. 102 void UpdateWindowShape(); 103 104 // Checks to see if the mouse pointer at |x|, |y| is over the border of the 105 // custom frame (a spot that should trigger a window resize). Returns true if 106 // it should and sets |edge|. 107 bool GetWindowEdge(int x, int y, GdkWindowEdge* edge) const; 108 109 // Connect/disconnect accelerators for keyboard shortcut support. 110 void ConnectAccelerators(); 111 void DisconnectAccelerators(); 112 113 // Returns the image to paint the frame. 114 gfx::Image GetFrameBackground() const; 115 116 // Animation when panel is first shown. 117 void RevealPanel(); 118 119 // Creates helper for handling drags if not already created. 120 void EnsureDragHelperCreated(); 121 122 void SetBoundsInternal(const gfx::Rect& bounds); 123 124 void LoadingAnimationCallback(); 125 126 // Returns the size of the window frame around the client content area. 127 gfx::Size GetNonClientFrameSize() const; 128 129 // Invalidate window to force repaint. 130 void InvalidateWindow(); 131 132 // Callback for accelerator activation. |user_data| stores the command id 133 // of the matched accelerator. 134 static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group, 135 GObject* acceleratable, 136 guint keyval, 137 GdkModifierType modifier, 138 void* user_data); 139 140 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMainWindowDeleteEvent, 141 GdkEvent*); 142 CHROMEGTK_CALLBACK_0(PanelGtk, void, OnMainWindowDestroy); 143 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnConfigure, GdkEventConfigure*); 144 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnWindowState, GdkEventWindowState*); 145 // Callback for when the custom frame alignment needs to be redrawn. 146 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnCustomFrameExpose, 147 GdkEventExpose*); 148 // Key press event callback. 149 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnKeyPress, GdkEventKey*); 150 // Mouse move and button press callbacks. If mouse hits titlebar, 151 // the titlebar gets the event, else the window gets the button press. 152 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMouseMoveEvent, 153 GdkEventMotion*); 154 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnButtonPressEvent, 155 GdkEventButton*); 156 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, 157 OnTitlebarButtonPressEvent, GdkEventButton*); 158 CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, 159 OnTitlebarButtonReleaseEvent, GdkEventButton*); 160 161 scoped_ptr<Panel> panel_; 162 gfx::Rect bounds_; 163 164 // True if the panel should always stay on top of other windows. 165 bool always_on_top_; 166 167 // True after panel has been shown. 168 bool is_shown_; 169 170 scoped_ptr<PanelDragGtk> drag_helper_; 171 172 // The configure size of the current window, used to figure out whether to 173 // ignore later configure events. See OnConfigure() for more information. 174 gfx::Size configure_size_; 175 176 // Indicates different painting state, active, drawing attention or else. 177 PaintState paint_state_; 178 179 // Indicates that the panel is currently drawing attention. 180 bool is_drawing_attention_; 181 182 // The timer used to update frames for the Loading Animation. 183 base::RepeatingTimer<PanelGtk> loading_animation_timer_; 184 185 // The current window cursor. We set it to a resize cursor when over the 186 // custom frame border. We set it to NULL if we want the default cursor. 187 GdkCursor* frame_cursor_; 188 189 // True if the window manager thinks the window is active. Not all window 190 // managers keep track of this state (_NET_ACTIVE_WINDOW), in which case 191 // this will always be true. 192 bool is_active_; 193 194 // True if the window manager thinks the window is minimized (iconified). 195 // Not all window managers support this, in which case this will always be 196 // false. 197 bool is_minimized_; 198 199 // Top level window. 200 GtkWindow* window_; 201 // GtkAlignment that holds the interior components of the chromium window. 202 // This is used to draw the custom frame border and content shadow. 203 GtkWidget* window_container_; 204 // VBox that holds everything (titlebar, web contents). 205 GtkWidget* window_vbox_; 206 // EventBox that holds web contents. 207 GtkWidget* render_area_event_box_; 208 // We insert and remove WebContents GtkWidgets into this expanded. 209 GtkWidget* contents_expanded_; 210 211 // The accelerator group used to handle accelerators, owned by this object. 212 GtkAccelGroup* accel_group_; 213 214 // The container for the titlebar. 215 scoped_ptr<PanelTitlebarGtk> titlebar_; 216 217 // Indicates how the window corner should be rendered, rounded or not. 218 panel::CornerStyle corner_style_; 219 220 DISALLOW_COPY_AND_ASSIGN(PanelGtk); 221 }; 222 223 #endif // CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_ 224