Chromium Code Reviews| 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..b2725af7d3f7a97bab7e13daaa6719416d20f077 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,39 @@ 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) { |
| + guint32 last_click_time = last_click_time_; |
| + gfx::Point last_click_position = last_click_position_; |
| + last_click_time_ = event->time; |
| + last_click_position_ = gfx::Point(static_cast<int>(event->x), |
|
Evan Stade
2012/08/15 21:20:40
you could share more code if you passed &last_clic
|
| + static_cast<int>(event->y)); |
| + |
| + if (!suppress_window_raise_) |
| + gdk_window_raise(GTK_WIDGET(widget)->window); |
| + |
| + return gtk_window_util::HandleTitleBarLeftMousePress(GTK_WINDOW(widget), |
| + bounds_, event, last_click_time, last_click_position); |
| + } else if (event->type == GDK_2BUTTON_PRESS) { |
|
Evan Stade
2012/08/15 21:20:40
nit: it's weird that the if and the else if cases
|
| + bool is_maximized_ = gdk_window_get_state(GTK_WIDGET(widget)->window) & |
|
Evan Stade
2012/08/15 21:20:40
first, local variables should not have final under
|
| + GDK_WINDOW_STATE_MAXIMIZED; |
| + is_maximized_ ? gtk_window_unmaximize(GTK_WINDOW(widget)) : |
| + 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 +267,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, |