Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ui / views / widget / desktop_aura / x11_window_event_filter.cc
index 740e120..887bb97 100644 (file)
@@ -9,12 +9,16 @@
 #include <X11/Xatom.h>
 #include <X11/Xlib.h>
 
-#include "ui/aura/root_window.h"
+#include "ui/aura/client/aura_constants.h"
+#include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
+#include "ui/aura/window_tree_host.h"
 #include "ui/base/hit_test.h"
 #include "ui/events/event.h"
 #include "ui/events/event_utils.h"
 #include "ui/gfx/x/x11_types.h"
+#include "ui/views/linux_ui/linux_ui.h"
+#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h"
 #include "ui/views/widget/native_widget_aura.h"
 
 namespace {
@@ -58,12 +62,14 @@ const char* kAtomsToCache[] = {
 namespace views {
 
 X11WindowEventFilter::X11WindowEventFilter(
-    aura::RootWindow* root_window)
+    DesktopWindowTreeHost* window_tree_host)
     : xdisplay_(gfx::GetXDisplay()),
-      xwindow_(root_window->GetAcceleratedWidget()),
+      xwindow_(window_tree_host->AsWindowTreeHost()->GetAcceleratedWidget()),
       x_root_window_(DefaultRootWindow(xdisplay_)),
       atom_cache_(xdisplay_, kAtomsToCache),
-      is_active_(false) {
+      window_tree_host_(window_tree_host),
+      is_active_(false),
+      click_component_(HTNOWHERE) {
 }
 
 X11WindowEventFilter::~X11WindowEventFilter() {
@@ -90,24 +96,83 @@ void X11WindowEventFilter::OnMouseEvent(ui::MouseEvent* event) {
   if (event->type() != ui::ET_MOUSE_PRESSED)
     return;
 
-  if (!event->IsLeftMouseButton())
+  if (!(event->IsLeftMouseButton() || event->IsMiddleMouseButton()))
     return;
 
   aura::Window* target = static_cast<aura::Window*>(event->target());
+  if (!target->delegate())
+    return;
+
+  int previous_click_component = HTNOWHERE;
   int component =
       target->delegate()->GetNonClientComponent(event->location());
+  if (event->IsLeftMouseButton()) {
+    previous_click_component = click_component_;
+    click_component_ = component;
+  }
   if (component == HTCLIENT)
     return;
 
+  if (event->IsMiddleMouseButton() && (component == HTCAPTION)) {
+    LinuxUI::NonClientMiddleClickAction action =
+        LinuxUI::MIDDLE_CLICK_ACTION_LOWER;
+    LinuxUI* linux_ui = LinuxUI::instance();
+    if (linux_ui)
+      action = linux_ui->GetNonClientMiddleClickAction();
+
+    switch (action) {
+      case LinuxUI::MIDDLE_CLICK_ACTION_NONE:
+        break;
+      case LinuxUI::MIDDLE_CLICK_ACTION_LOWER:
+        XLowerWindow(xdisplay_, xwindow_);
+        break;
+      case LinuxUI::MIDDLE_CLICK_ACTION_MINIMIZE:
+        window_tree_host_->Minimize();
+        break;
+      case LinuxUI::MIDDLE_CLICK_ACTION_TOGGLE_MAXIMIZE:
+        if (target->GetProperty(aura::client::kCanMaximizeKey))
+          ToggleMaximizedState();
+        break;
+    }
+
+    event->SetHandled();
+    return;
+  }
+
+  // Left button case.
+  if (event->flags() & ui::EF_IS_DOUBLE_CLICK) {
+    click_component_ = HTNOWHERE;
+    if (component == HTCAPTION &&
+        target->GetProperty(aura::client::kCanMaximizeKey) &&
+        previous_click_component == component) {
+      // Our event is a double click in the caption area in a window that can be
+      // maximized. We are responsible for dispatching this as a minimize/
+      // maximize on X11 (Windows converts this to min/max events for us).
+      ToggleMaximizedState();
+      event->SetHandled();
+      return;
+    }
+  }
+
   // Get the |x_root_window_| location out of the native event.
   if (event->native_event()) {
     const gfx::Point x_root_location =
         ui::EventSystemLocationFromNative(event->native_event());
-    if (DispatchHostWindowDragMovement(component, x_root_location))
+    if ((component == HTCAPTION ||
+         target->GetProperty(aura::client::kCanResizeKey)) &&
+        DispatchHostWindowDragMovement(component, x_root_location)) {
       event->StopPropagation();
+    }
   }
 }
 
+void X11WindowEventFilter::ToggleMaximizedState() {
+  if (window_tree_host_->IsMaximized())
+    window_tree_host_->Restore();
+  else
+    window_tree_host_->Maximize();
+}
+
 bool X11WindowEventFilter::DispatchHostWindowDragMovement(
     int hittest,
     const gfx::Point& screen_location) {