OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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_BROWSER_WINDOW_GTK_H_ |
| 6 #define CHROME_BROWSER_UI_GTK_BROWSER_WINDOW_GTK_H_ |
| 7 #pragma once |
| 8 |
| 9 #include <gtk/gtk.h> |
| 10 |
| 11 #include <map> |
| 12 |
| 13 #include "app/active_window_watcher_x.h" |
| 14 #include "app/gtk_signal.h" |
| 15 #include "app/x11_util.h" |
| 16 #include "base/scoped_ptr.h" |
| 17 #include "base/timer.h" |
| 18 #include "build/build_config.h" |
| 19 #include "chrome/browser/browser_window.h" |
| 20 #include "chrome/browser/gtk/infobar_arrow_model.h" |
| 21 #include "chrome/browser/prefs/pref_member.h" |
| 22 #include "chrome/browser/tabs/tab_strip_model_observer.h" |
| 23 #include "chrome/common/notification_registrar.h" |
| 24 #include "gfx/rect.h" |
| 25 |
| 26 class BookmarkBarGtk; |
| 27 class Browser; |
| 28 class BrowserTitlebar; |
| 29 class BrowserToolbarGtk; |
| 30 class CustomDrawButton; |
| 31 class DownloadShelfGtk; |
| 32 class FindBarGtk; |
| 33 class FullscreenExitBubbleGtk; |
| 34 class InfoBarContainerGtk; |
| 35 class LocationBar; |
| 36 class StatusBubbleGtk; |
| 37 class TabContentsContainerGtk; |
| 38 class TabStripGtk; |
| 39 |
| 40 // An implementation of BrowserWindow for GTK. |
| 41 // Cross-platform code will interact with this object when |
| 42 // it needs to manipulate the window. |
| 43 |
| 44 class BrowserWindowGtk : public BrowserWindow, |
| 45 public NotificationObserver, |
| 46 public TabStripModelObserver, |
| 47 public ActiveWindowWatcherX::Observer, |
| 48 public InfoBarArrowModel::Observer { |
| 49 public: |
| 50 explicit BrowserWindowGtk(Browser* browser); |
| 51 virtual ~BrowserWindowGtk(); |
| 52 |
| 53 // Overridden from BrowserWindow |
| 54 virtual void Show(); |
| 55 virtual void SetBounds(const gfx::Rect& bounds); |
| 56 virtual void Close(); |
| 57 virtual void Activate(); |
| 58 virtual void Deactivate(); |
| 59 virtual bool IsActive() const; |
| 60 virtual void FlashFrame(); |
| 61 virtual gfx::NativeWindow GetNativeHandle(); |
| 62 virtual BrowserWindowTesting* GetBrowserWindowTesting(); |
| 63 virtual StatusBubble* GetStatusBubble(); |
| 64 virtual void SelectedTabToolbarSizeChanged(bool is_animating); |
| 65 virtual void UpdateTitleBar(); |
| 66 virtual void ShelfVisibilityChanged(); |
| 67 virtual void UpdateDevTools(); |
| 68 virtual void UpdateLoadingAnimations(bool should_animate); |
| 69 virtual void SetStarredState(bool is_starred); |
| 70 virtual gfx::Rect GetRestoredBounds() const; |
| 71 virtual bool IsMaximized() const; |
| 72 virtual void SetFullscreen(bool fullscreen); |
| 73 virtual bool IsFullscreen() const; |
| 74 virtual bool IsFullscreenBubbleVisible() const; |
| 75 virtual LocationBar* GetLocationBar() const; |
| 76 virtual void SetFocusToLocationBar(bool select_all); |
| 77 virtual void UpdateReloadStopState(bool is_loading, bool force); |
| 78 virtual void UpdateToolbar(TabContentsWrapper* contents, |
| 79 bool should_restore_state); |
| 80 virtual void FocusToolbar(); |
| 81 virtual void FocusAppMenu(); |
| 82 virtual void FocusBookmarksToolbar(); |
| 83 virtual void FocusChromeOSStatus(); |
| 84 virtual void RotatePaneFocus(bool forwards); |
| 85 virtual bool IsBookmarkBarVisible() const; |
| 86 virtual bool IsBookmarkBarAnimating() const; |
| 87 virtual bool IsTabStripEditable() const; |
| 88 virtual bool IsToolbarVisible() const; |
| 89 virtual void ConfirmAddSearchProvider(const TemplateURL* template_url, |
| 90 Profile* profile); |
| 91 virtual void ToggleBookmarkBar(); |
| 92 virtual views::Window* ShowAboutChromeDialog(); |
| 93 virtual void ShowUpdateChromeDialog(); |
| 94 virtual void ShowTaskManager(); |
| 95 virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked); |
| 96 virtual bool IsDownloadShelfVisible() const; |
| 97 virtual DownloadShelf* GetDownloadShelf(); |
| 98 virtual void ShowClearBrowsingDataDialog(); |
| 99 virtual void ShowImportDialog(); |
| 100 virtual void ShowSearchEnginesDialog(); |
| 101 virtual void ShowPasswordManager(); |
| 102 virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); |
| 103 virtual void ShowContentSettingsWindow(ContentSettingsType content_type, |
| 104 Profile* profile); |
| 105 virtual void ShowCollectedCookiesDialog(TabContents* tab_contents); |
| 106 virtual void ShowProfileErrorDialog(int message_id); |
| 107 virtual void ShowThemeInstallBubble(); |
| 108 virtual void ConfirmBrowserCloseWithPendingDownloads(); |
| 109 virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, |
| 110 gfx::NativeWindow parent_window); |
| 111 virtual void UserChangedTheme(); |
| 112 virtual int GetExtraRenderViewHeight() const; |
| 113 virtual void TabContentsFocused(TabContents* tab_contents); |
| 114 virtual void ShowPageInfo(Profile* profile, |
| 115 const GURL& url, |
| 116 const NavigationEntry::SSLStatus& ssl, |
| 117 bool show_history); |
| 118 virtual void ShowAppMenu(); |
| 119 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, |
| 120 bool* is_keyboard_shortcut); |
| 121 virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event); |
| 122 virtual void ShowCreateWebAppShortcutsDialog(TabContents* tab_contents); |
| 123 virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile, |
| 124 const Extension* app); |
| 125 virtual void Cut(); |
| 126 virtual void Copy(); |
| 127 virtual void Paste(); |
| 128 virtual void ToggleTabStripMode() {} |
| 129 virtual void PrepareForInstant(); |
| 130 virtual void ShowInstant(TabContents* preview_contents); |
| 131 virtual void HideInstant(bool instant_is_active); |
| 132 virtual gfx::Rect GetInstantBounds(); |
| 133 |
| 134 virtual gfx::Rect GrabWindowSnapshot( |
| 135 std::vector<unsigned char>* png_representation); |
| 136 |
| 137 // Overridden from NotificationObserver: |
| 138 virtual void Observe(NotificationType type, |
| 139 const NotificationSource& source, |
| 140 const NotificationDetails& details); |
| 141 |
| 142 // Overridden from TabStripModelObserver: |
| 143 virtual void TabDetachedAt(TabContentsWrapper* contents, int index); |
| 144 virtual void TabSelectedAt(TabContentsWrapper* old_contents, |
| 145 TabContentsWrapper* new_contents, |
| 146 int index, |
| 147 bool user_gesture); |
| 148 |
| 149 // Overridden from ActiveWindowWatcher::Observer. |
| 150 virtual void ActiveWindowChanged(GdkWindow* active_window); |
| 151 |
| 152 // Overridden from InfoBarArrowModel::Observer. |
| 153 virtual void PaintStateChanged(); |
| 154 |
| 155 // Accessor for the tab strip. |
| 156 TabStripGtk* tabstrip() const { return tabstrip_.get(); } |
| 157 |
| 158 void UpdateDevToolsForContents(TabContents* contents); |
| 159 |
| 160 void OnBoundsChanged(const gfx::Rect& bounds); |
| 161 void OnDebouncedBoundsChanged(); |
| 162 void OnStateChanged(GdkWindowState state, GdkWindowState changed_mask); |
| 163 |
| 164 // Request the underlying window to unmaximize. Also tries to work around |
| 165 // a window manager "feature" that can prevent this in some edge cases. |
| 166 void UnMaximize(); |
| 167 |
| 168 // Returns false if we're not ready to close yet. E.g., a tab may have an |
| 169 // onbeforeunload handler that prevents us from closing. |
| 170 bool CanClose() const; |
| 171 |
| 172 bool ShouldShowWindowIcon() const; |
| 173 |
| 174 // Add the find bar widget to the window hierarchy. |
| 175 void AddFindBar(FindBarGtk* findbar); |
| 176 |
| 177 // Reset the mouse cursor to the default cursor if it was set to something |
| 178 // else for the custom frame. |
| 179 void ResetCustomFrameCursor(); |
| 180 |
| 181 // Toggles whether an infobar is showing. |
| 182 // |animate| controls whether we animate to the new state set by |bar|. |
| 183 void SetInfoBarShowing(InfoBar* bar, bool animate); |
| 184 |
| 185 // Returns the BrowserWindowGtk registered with |window|. |
| 186 static BrowserWindowGtk* GetBrowserWindowForNativeWindow( |
| 187 gfx::NativeWindow window); |
| 188 |
| 189 // Retrieves the GtkWindow associated with |xid|, which is the X Window |
| 190 // ID of the top-level X window of this object. |
| 191 static GtkWindow* GetBrowserWindowForXID(XID xid); |
| 192 |
| 193 Browser* browser() const { return browser_.get(); } |
| 194 |
| 195 GtkWindow* window() const { return window_; } |
| 196 |
| 197 BrowserToolbarGtk* GetToolbar() { return toolbar_.get(); } |
| 198 |
| 199 gfx::Rect bounds() const { return bounds_; } |
| 200 |
| 201 // Make changes necessary when the floating state of the bookmark bar changes. |
| 202 // This should only be called by the bookmark bar itself. |
| 203 void BookmarkBarIsFloating(bool is_floating); |
| 204 |
| 205 // Returns the tab contents we're currently displaying in the tab contents |
| 206 // container. |
| 207 TabContents* GetDisplayedTabContents(); |
| 208 |
| 209 static void RegisterUserPrefs(PrefService* prefs); |
| 210 |
| 211 // Returns whether to draw the content drop shadow on the sides and bottom |
| 212 // of the browser window. When false, we still draw a shadow on the top of |
| 213 // the toolbar (under the tab strip), but do not round the top corners. |
| 214 bool ShouldDrawContentDropShadow(); |
| 215 |
| 216 // Tells GTK that the toolbar area is invalidated and needs redrawing. We |
| 217 // have this method as a hack because GTK doesn't queue the toolbar area for |
| 218 // redraw when it should. |
| 219 void QueueToolbarRedraw(); |
| 220 |
| 221 // Get the position where the infobar arrow should be anchored in |
| 222 // |relative_to| coordinates. This is the middle of the omnibox location icon. |
| 223 int GetXPositionOfLocationIcon(GtkWidget* relative_to); |
| 224 |
| 225 protected: |
| 226 virtual void DestroyBrowser(); |
| 227 // Top level window. |
| 228 GtkWindow* window_; |
| 229 // GtkAlignment that holds the interior components of the chromium window. |
| 230 // This is used to draw the custom frame border and content shadow. |
| 231 GtkWidget* window_container_; |
| 232 // VBox that holds everything (tabs, toolbar, bookmarks bar, tab contents). |
| 233 GtkWidget* window_vbox_; |
| 234 // VBox that holds everything below the toolbar. |
| 235 GtkWidget* render_area_vbox_; |
| 236 // Floating container that holds the render area. It is needed to position |
| 237 // the findbar. |
| 238 GtkWidget* render_area_floating_container_; |
| 239 // EventBox that holds render_area_floating_container_. |
| 240 GtkWidget* render_area_event_box_; |
| 241 // Border between toolbar and render area. |
| 242 GtkWidget* toolbar_border_; |
| 243 |
| 244 scoped_ptr<Browser> browser_; |
| 245 |
| 246 // The download shelf view (view at the bottom of the page). |
| 247 scoped_ptr<DownloadShelfGtk> download_shelf_; |
| 248 |
| 249 private: |
| 250 // Show or hide the bookmark bar. |
| 251 void MaybeShowBookmarkBar(bool animate); |
| 252 |
| 253 // Sets the default size for the window and the the way the user is allowed to |
| 254 // resize it. |
| 255 void SetGeometryHints(); |
| 256 |
| 257 // Connect to signals on |window_|. |
| 258 void ConnectHandlersToSignals(); |
| 259 |
| 260 // Create the various UI components. |
| 261 void InitWidgets(); |
| 262 |
| 263 // Set up background color of the window (depends on if we're incognito or |
| 264 // not). |
| 265 void SetBackgroundColor(); |
| 266 |
| 267 // Called when the window size changed. |
| 268 void OnSizeChanged(int width, int height); |
| 269 |
| 270 // Applies the window shape to if we're in custom drawing mode. |
| 271 void UpdateWindowShape(int width, int height); |
| 272 |
| 273 // Connect accelerators that aren't connected to menu items (like ctrl-o, |
| 274 // ctrl-l, etc.). |
| 275 void ConnectAccelerators(); |
| 276 |
| 277 // Change whether we're showing the custom blue frame. |
| 278 // Must be called once at startup. |
| 279 // Triggers relayout of the content. |
| 280 void UpdateCustomFrame(); |
| 281 |
| 282 // Save the window position in the prefs. |
| 283 void SaveWindowPosition(); |
| 284 |
| 285 // Set the bounds of the current window. If |exterior| is true, set the size |
| 286 // of the window itself, otherwise set the bounds of the web contents. |
| 287 // If |move| is true, set the position of the window, otherwise leave the |
| 288 // position to the WM. |
| 289 void SetBoundsImpl(const gfx::Rect& bounds, bool exterior, bool move); |
| 290 |
| 291 // Callback for when the custom frame alignment needs to be redrawn. |
| 292 // The content area includes the toolbar and web page but not the tab strip. |
| 293 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnCustomFrameExpose, |
| 294 GdkEventExpose*); |
| 295 |
| 296 // A helper method that draws the shadow above the toolbar and in the frame |
| 297 // border during an expose. |
| 298 void DrawContentShadow(cairo_t* cr); |
| 299 |
| 300 // Draws the tab image as the frame so we can write legible text. |
| 301 void DrawPopupFrame(cairo_t* cr, GtkWidget* widget, GdkEventExpose* event); |
| 302 |
| 303 // Draws the normal custom frame using theme_frame. |
| 304 void DrawCustomFrame(cairo_t* cr, GtkWidget* widget, GdkEventExpose* event); |
| 305 |
| 306 // The background frame image needs to be offset by the size of the top of |
| 307 // the window to the top of the tabs when the full skyline isn't displayed |
| 308 // for some reason. |
| 309 int GetVerticalOffset(); |
| 310 |
| 311 // Returns which frame image we should use based on the window's current |
| 312 // activation state / incognito state. |
| 313 int GetThemeFrameResource(); |
| 314 |
| 315 // Invalidate all the widgets that need to redraw when the infobar draw state |
| 316 // has changed. |
| 317 void InvalidateInfoBarBits(); |
| 318 |
| 319 // When the location icon moves, we have to redraw the arrow. |
| 320 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, void, OnLocationIconSizeAllocate, |
| 321 GtkAllocation*); |
| 322 |
| 323 // Used to draw the infobar arrow and drop shadow. This is connected to |
| 324 // multiple widgets' expose events because it overlaps several widgets. |
| 325 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnExposeDrawInfobarBits, |
| 326 GdkEventExpose*); |
| 327 |
| 328 // Used to draw the infobar bits for the bookmark bar. When the bookmark |
| 329 // bar is in floating mode, it has to draw a drop shadow only; otherwise |
| 330 // it is responsible for its portion of the arrow as well as some shadowing. |
| 331 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnBookmarkBarExpose, |
| 332 GdkEventExpose*); |
| 333 |
| 334 // Callback for "size-allocate" signal on bookmark bar; this is relevant |
| 335 // because when the bookmark bar changes dimensions, the infobar arrow has to |
| 336 // change its shape, and we need to queue appropriate redraws. |
| 337 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, void, OnBookmarkBarSizeAllocate, |
| 338 GtkAllocation*); |
| 339 |
| 340 // Callback for accelerator activation. |user_data| stores the command id |
| 341 // of the matched accelerator. |
| 342 static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group, |
| 343 GObject* acceleratable, |
| 344 guint keyval, |
| 345 GdkModifierType modifier, |
| 346 void* user_data); |
| 347 |
| 348 // Key press event callback. |
| 349 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnKeyPress, GdkEventKey*); |
| 350 |
| 351 // Mouse move and mouse button press callbacks. |
| 352 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnMouseMoveEvent, |
| 353 GdkEventMotion*); |
| 354 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnButtonPressEvent, |
| 355 GdkEventButton*); |
| 356 |
| 357 // Maps and Unmaps the xid of |widget| to |window|. |
| 358 static void MainWindowMapped(GtkWidget* widget); |
| 359 static void MainWindowUnMapped(GtkWidget* widget); |
| 360 |
| 361 // Tracks focus state of browser. |
| 362 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnFocusIn, |
| 363 GdkEventFocus*); |
| 364 CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnFocusOut, |
| 365 GdkEventFocus*); |
| 366 |
| 367 // Callback for the loading animation(s) associated with this window. |
| 368 void LoadingAnimationCallback(); |
| 369 |
| 370 // Shows UI elements for supported window features. |
| 371 void ShowSupportedWindowFeatures(); |
| 372 |
| 373 // Hides UI elements for unsupported window features. |
| 374 void HideUnsupportedWindowFeatures(); |
| 375 |
| 376 // Helper functions that query |browser_| concerning support for UI features |
| 377 // in this window. (For example, a popup window might not support a tabstrip). |
| 378 bool IsTabStripSupported() const; |
| 379 bool IsToolbarSupported() const; |
| 380 bool IsBookmarkBarSupported() const; |
| 381 |
| 382 // Whether we should draw the tab background instead of the theme_frame |
| 383 // background because this window is a popup. |
| 384 bool UsingCustomPopupFrame() const; |
| 385 |
| 386 // Checks to see if the mouse pointer at |x|, |y| is over the border of the |
| 387 // custom frame (a spot that should trigger a window resize). Returns true if |
| 388 // it should and sets |edge|. |
| 389 bool GetWindowEdge(int x, int y, GdkWindowEdge* edge); |
| 390 |
| 391 // Returns |true| if we should use the custom frame. |
| 392 bool UseCustomFrame(); |
| 393 |
| 394 // Returns |true| if the window bounds match the monitor size. |
| 395 bool BoundsMatchMonitorSize(); |
| 396 |
| 397 // Put the bookmark bar where it belongs. |
| 398 void PlaceBookmarkBar(bool is_floating); |
| 399 |
| 400 // Determine whether we use should default to native decorations or the custom |
| 401 // frame based on the currently-running window manager. |
| 402 static bool GetCustomFramePrefDefault(); |
| 403 |
| 404 NotificationRegistrar registrar_; |
| 405 |
| 406 // The position and size of the current window. |
| 407 gfx::Rect bounds_; |
| 408 |
| 409 // The position and size of the non-maximized, non-fullscreen window. |
| 410 gfx::Rect restored_bounds_; |
| 411 |
| 412 GdkWindowState state_; |
| 413 |
| 414 // The container for the titlebar + tab strip. |
| 415 scoped_ptr<BrowserTitlebar> titlebar_; |
| 416 |
| 417 // The object that manages all of the widgets in the toolbar. |
| 418 scoped_ptr<BrowserToolbarGtk> toolbar_; |
| 419 |
| 420 // The object that manages the bookmark bar. This will be NULL if the |
| 421 // bookmark bar is not supported. |
| 422 scoped_ptr<BookmarkBarGtk> bookmark_bar_; |
| 423 |
| 424 // Caches the hover state of the bookmark bar. |
| 425 bool bookmark_bar_is_floating_; |
| 426 |
| 427 // The status bubble manager. Always non-NULL. |
| 428 scoped_ptr<StatusBubbleGtk> status_bubble_; |
| 429 |
| 430 // A container that manages the GtkWidget*s that are the webpage display |
| 431 // (along with associated infobars, shelves, and other things that are part |
| 432 // of the content area). |
| 433 scoped_ptr<TabContentsContainerGtk> contents_container_; |
| 434 |
| 435 // A container that manages the GtkWidget*s of developer tools for the |
| 436 // selected tab contents. |
| 437 scoped_ptr<TabContentsContainerGtk> devtools_container_; |
| 438 |
| 439 // Split pane containing the contents_container_ and the devtools_container_. |
| 440 GtkWidget* contents_split_; |
| 441 |
| 442 // The tab strip. Always non-NULL. |
| 443 scoped_ptr<TabStripGtk> tabstrip_; |
| 444 |
| 445 // The container for info bars. Always non-NULL. |
| 446 scoped_ptr<InfoBarContainerGtk> infobar_container_; |
| 447 |
| 448 // The timer used to update frames for the Loading Animation. |
| 449 base::RepeatingTimer<BrowserWindowGtk> loading_animation_timer_; |
| 450 |
| 451 // The timer used to save the window position for session restore. |
| 452 base::OneShotTimer<BrowserWindowGtk> window_configure_debounce_timer_; |
| 453 |
| 454 // Whether the custom chrome frame pref is set. Normally you want to use |
| 455 // UseCustomFrame() above to determine whether to use the custom frame or |
| 456 // not. |
| 457 BooleanPrefMember use_custom_frame_pref_; |
| 458 |
| 459 // A map which translates an X Window ID into its respective GtkWindow. |
| 460 static std::map<XID, GtkWindow*> xid_map_; |
| 461 |
| 462 // The current window cursor. We set it to a resize cursor when over the |
| 463 // custom frame border. We set it to NULL if we want the default cursor. |
| 464 GdkCursor* frame_cursor_; |
| 465 |
| 466 // True if the window manager thinks the window is active. Not all window |
| 467 // managers keep track of this state (_NET_ACTIVE_WINDOW), in which case |
| 468 // this will always be true. |
| 469 bool is_active_; |
| 470 |
| 471 // Keep track of the last click time and the last click position so we can |
| 472 // filter out extra GDK_BUTTON_PRESS events when a double click happens. |
| 473 guint32 last_click_time_; |
| 474 gfx::Point last_click_position_; |
| 475 |
| 476 // If true, maximize the window after we call BrowserWindow::Show for the |
| 477 // first time. This is to work around a compiz bug. |
| 478 bool maximize_after_show_; |
| 479 |
| 480 // If true, don't call gdk_window_raise() when we get a click in the title |
| 481 // bar or window border. This is to work around a compiz bug. |
| 482 bool suppress_window_raise_; |
| 483 |
| 484 // The accelerator group used to handle accelerators, owned by this object. |
| 485 GtkAccelGroup* accel_group_; |
| 486 |
| 487 scoped_ptr<FullscreenExitBubbleGtk> fullscreen_exit_bubble_; |
| 488 |
| 489 // The model that tracks the paint state of the arrow for the infobar |
| 490 // directly below the toolbar. |
| 491 InfoBarArrowModel infobar_arrow_model_; |
| 492 |
| 493 DISALLOW_COPY_AND_ASSIGN(BrowserWindowGtk); |
| 494 }; |
| 495 |
| 496 #endif // CHROME_BROWSER_UI_GTK_BROWSER_WINDOW_GTK_H_ |
OLD | NEW |