| Index: chrome/browser/ui/gtk/extensions/shell_window_gtk.cc
|
| diff --git a/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc b/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc
|
| index fe265587ee8c9cceafbeef1ab90330e5314af283..de0838310b5df557c02e32d7bfdaa824de2b26ad 100644
|
| --- a/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc
|
| +++ b/chrome/browser/ui/gtk/extensions/shell_window_gtk.cc
|
| @@ -5,6 +5,8 @@
|
| #include "chrome/browser/ui/gtk/extensions/shell_window_gtk.h"
|
|
|
| #include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/ui/gtk/gtk_window_util.h"
|
| +#include "chrome/common/extensions/draggable_region.h"
|
| #include "chrome/common/extensions/extension.h"
|
| #include "content/public/browser/render_view_host.h"
|
| #include "content/public/browser/render_widget_host_view.h"
|
| @@ -20,7 +22,8 @@ ShellWindowGtk::ShellWindowGtk(Profile* profile,
|
| : ShellWindow(profile, extension, url),
|
| state_(GDK_WINDOW_STATE_WITHDRAWN),
|
| is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()),
|
| - content_thinks_its_fullscreen_(false) {
|
| + content_thinks_its_fullscreen_(false),
|
| + frameless_(params.frame == ShellWindow::CreateParams::FRAME_NONE) {
|
| window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
|
|
| gfx::NativeView native_view =
|
| @@ -31,7 +34,7 @@ ShellWindowGtk::ShellWindowGtk(Profile* profile,
|
| window_, params.bounds.width(), params.bounds.height());
|
|
|
| // Hide titlebar when {frame: 'none'} specified on ShellWindow.
|
| - if (params.frame == ShellWindow::CreateParams::FRAME_NONE)
|
| + if (frameless_)
|
| gtk_window_set_decorated(window_, false);
|
|
|
| int min_width = params.minimum_size.width();
|
| @@ -58,6 +61,13 @@ ShellWindowGtk::ShellWindowGtk(Profile* profile,
|
| static_cast<GdkWindowHints>(hints_mask));
|
| }
|
|
|
| + // In some (older) versions of compiz, raising top-level windows when they
|
| + // are partially off-screen causes them to get snapped back on screen, not
|
| + // always even on the current virtual desktop. If we are running under
|
| + // compiz, suppress such raises, as they are not necessary in compiz anyway.
|
| + if (ui::GuessWindowManager() == ui::WM_COMPIZ)
|
| + suppress_window_raise_ = true;
|
| +
|
| // TODO(mihaip): Mirror contents of <title> tag in window title
|
| gtk_window_set_title(window_, extension->name().c_str());
|
|
|
| @@ -67,6 +77,10 @@ ShellWindowGtk::ShellWindowGtk(Profile* profile,
|
| G_CALLBACK(OnConfigureThunk), this);
|
| g_signal_connect(window_, "window-state-event",
|
| G_CALLBACK(OnWindowStateThunk), this);
|
| + if (frameless_) {
|
| + g_signal_connect(window_, "button-press-event",
|
| + G_CALLBACK(OnButtonPressThunk), this);
|
| + }
|
|
|
| ui::ActiveWindowWatcherX::AddObserver(this);
|
| }
|
| @@ -208,6 +222,37 @@ gboolean ShellWindowGtk::OnWindowState(GtkWidget* sender,
|
| return FALSE;
|
| }
|
|
|
| +gboolean ShellWindowGtk::OnButtonPress(GtkWidget* widget,
|
| + GdkEventButton* event) {
|
| + if (!draggable_region_.isEmpty() &&
|
| + draggable_region_.contains(event->x, event->y)) {
|
| + if (event->button == 1) {
|
| + if (GDK_BUTTON_PRESS == event->type) {
|
| + if (!suppress_window_raise_)
|
| + gdk_window_raise(GTK_WIDGET(widget)->window);
|
| +
|
| + return gtk_window_util::HandleTitleBarLeftMousePress(
|
| + GTK_WINDOW(widget), bounds_, event);
|
| + } else if (GDK_2BUTTON_PRESS == event->type) {
|
| + bool is_maximized = gdk_window_get_state(GTK_WIDGET(widget)->window) &
|
| + GDK_WINDOW_STATE_MAXIMIZED;
|
| + if (is_maximized) {
|
| + gtk_window_util::UnMaximize(GTK_WINDOW(widget),
|
| + bounds_, restored_bounds_);
|
| + } else {
|
| + gtk_window_maximize(GTK_WINDOW(widget));
|
| + }
|
| + return TRUE;
|
| + }
|
| + } else if (event->button == 2) {
|
| + gdk_window_lower(GTK_WIDGET(widget)->window);
|
| + return TRUE;
|
| + }
|
| + }
|
| +
|
| + return FALSE;
|
| +}
|
| +
|
| void ShellWindowGtk::SetFullscreen(bool fullscreen) {
|
| content_thinks_its_fullscreen_ = fullscreen;
|
| if (fullscreen)
|
| @@ -220,6 +265,34 @@ bool ShellWindowGtk::IsFullscreenOrPending() const {
|
| return content_thinks_its_fullscreen_;
|
| }
|
|
|
| +void ShellWindowGtk::UpdateDraggableRegions(
|
| + const std::vector<extensions::DraggableRegion>& regions) {
|
| + // Draggable region is not supported for non-frameless window.
|
| + if (!frameless_)
|
| + return;
|
| +
|
| + SkRegion draggable_region;
|
| +
|
| + // By default, the whole window is draggable.
|
| + gfx::Rect bounds = GetBounds();
|
| + draggable_region.op(0, 0, bounds.right(), bounds.bottom(),
|
| + SkRegion::kUnion_Op);
|
| +
|
| + // Exclude those designated as non-draggable.
|
| + for (std::vector<extensions::DraggableRegion>::const_iterator iter =
|
| + regions.begin();
|
| + iter != regions.end(); ++iter) {
|
| + const extensions::DraggableRegion& region = *iter;
|
| + draggable_region.op(region.bounds.x(),
|
| + region.bounds.y(),
|
| + region.bounds.right(),
|
| + region.bounds.bottom(),
|
| + SkRegion::kDifference_Op);
|
| + }
|
| +
|
| + draggable_region_ = draggable_region;
|
| +}
|
| +
|
| // static
|
| ShellWindow* ShellWindow::CreateImpl(Profile* profile,
|
| const extensions::Extension* extension,
|
|
|