1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file. 4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/ui/views/panels/x11_panel_resizer.h" 6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/ui/panels/panel.h" 8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/ui/panels/panel_manager.h" 9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/aura/window.h" 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/aura/window_delegate.h" 11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/base/hit_test.h" 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/events/event.h" 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/events/event_utils.h" 14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/views/view.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace { 17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Returns true if the window can be resized via |component|. 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool IsWindowBorder(int component) { 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return component == HTBOTTOM || 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTBOTTOMLEFT || 22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTBOTTOMRIGHT || 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTLEFT || 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTRIGHT || 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTTOP || 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTTOPLEFT || 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) component == HTTOPRIGHT; 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace 31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)X11PanelResizer::X11PanelResizer(Panel* panel, aura::Window* window) 33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : panel_(panel), 34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) window_(window), 35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_state_(NOT_RESIZING), 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_component_(HTNOWHERE) { 37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)X11PanelResizer::~X11PanelResizer() { 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) StopResizing(NULL, true); 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void X11PanelResizer::OnMousePressed(ui::MouseEvent* event) { 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (resize_state_ != NOT_RESIZING || 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event->type() != ui::ET_MOUSE_PRESSED || 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !event->IsLeftMouseButton() || 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !event->native_event()) { 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int component = window_->delegate()->GetNonClientComponent(event->location()); 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!IsWindowBorder(component)) 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Set capture so that we get notified of all subsequent events. 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) window_->SetCapture(); 57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_state_ = RESIZE_CAN_START; 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) initial_press_location_in_screen_ = ui::EventSystemLocationFromNative( 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event->native_event()); 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_component_ = component; 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event->StopPropagation(); 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void X11PanelResizer::OnMouseDragged(ui::MouseEvent* event) { 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (resize_state_ != RESIZE_CAN_START && 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_state_ != RESIZE_IN_PROGRESS) { 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!event->native_event()) 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Get the location in screen coordinates from the XEvent because converting 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the mouse location to screen coordinates using ScreenPositionClient returns 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // an incorrect location while the panel is moving. See crbug.com/353393 for 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // more details. 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO: Fix conversion to screen coordinates. 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Point location_in_screen = ui::EventSystemLocationFromNative( 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event->native_event()); 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (resize_state_ == RESIZE_CAN_START) { 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Vector2d delta = 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) location_in_screen - initial_press_location_in_screen_; 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (views::View::ExceededDragThreshold(delta)) { 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_state_ = RESIZE_IN_PROGRESS; 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) panel_->manager()->StartResizingByMouse(panel_, location_in_screen, 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_component_); 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (resize_state_ == RESIZE_IN_PROGRESS) 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) panel_->manager()->ResizeByMouse(location_in_screen); 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event->StopPropagation(); 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void X11PanelResizer::StopResizing(ui::MouseEvent* event, bool canceled) { 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (resize_state_ == NOT_RESIZING) 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (resize_state_ == RESIZE_IN_PROGRESS) { 102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) panel_->manager()->EndResizingByMouse(canceled); 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) window_->ReleaseCapture(); 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (event) 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) event->StopPropagation(); 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resize_state_ = NOT_RESIZING; 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void X11PanelResizer::OnMouseEvent(ui::MouseEvent* event) { 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) switch (event->type()) { 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case ui::ET_MOUSE_PRESSED: 113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) OnMousePressed(event); 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case ui::ET_MOUSE_DRAGGED: 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) OnMouseDragged(event); 117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case ui::ET_MOUSE_RELEASED: 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) StopResizing(event, false); 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case ui::ET_MOUSE_CAPTURE_CHANGED: 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) StopResizing(event, true); 123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) default: 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) break; 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 128