Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: wm/host/root_window_host_linux.cc

Issue 11485006: Add window manager component. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address more review feedback Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/aura/root_window_host_linux.h" 5 #include "wm/host/root_window_host_linux.h"
6 6
7 #include <strings.h>
8 #include <X11/cursorfont.h>
9 #include <X11/extensions/Xfixes.h>
10 #include <X11/extensions/XInput2.h>
11 #include <X11/extensions/Xrandr.h>
12 #include <X11/Xatom.h> 7 #include <X11/Xatom.h>
13 #include <X11/Xcursor/Xcursor.h> 8 #include <X11/Xcursor/Xcursor.h>
14 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 #include <X11/cursorfont.h>
11 #include <X11/extensions/XInput2.h>
12 #include <X11/extensions/Xcomposite.h>
13 #include <X11/extensions/Xfixes.h>
14 #include <X11/extensions/Xrandr.h>
15 #include <X11/extensions/shape.h>
16 #include <strings.h>
15 17
16 #include <algorithm> 18 #include <algorithm>
17 #include <limits> 19 #include <limits>
18 #include <string> 20 #include <string>
19 21
20 #include "base/command_line.h" 22 #include "base/command_line.h"
21 #include "base/message_loop.h" 23 #include "base/message_loop.h"
22 #include "base/message_pump_aurax11.h" 24 #include "base/message_pump_aurax11.h"
23 #include "base/stl_util.h" 25 #include "base/stl_util.h"
24 #include "base/stringprintf.h" 26 #include "base/stringprintf.h"
(...skipping 13 matching lines...) Expand all
38 #include "ui/base/touch/touch_factory.h" 40 #include "ui/base/touch/touch_factory.h"
39 #include "ui/base/ui_base_switches.h" 41 #include "ui/base/ui_base_switches.h"
40 #include "ui/base/view_prop.h" 42 #include "ui/base/view_prop.h"
41 #include "ui/base/x/device_list_cache_x.h" 43 #include "ui/base/x/device_list_cache_x.h"
42 #include "ui/base/x/valuators.h" 44 #include "ui/base/x/valuators.h"
43 #include "ui/base/x/x11_util.h" 45 #include "ui/base/x/x11_util.h"
44 #include "ui/compositor/dip_util.h" 46 #include "ui/compositor/dip_util.h"
45 #include "ui/compositor/layer.h" 47 #include "ui/compositor/layer.h"
46 #include "ui/gfx/codec/png_codec.h" 48 #include "ui/gfx/codec/png_codec.h"
47 #include "ui/gfx/screen.h" 49 #include "ui/gfx/screen.h"
50 #include "wm/foreign_window.h"
51 #include "wm/foreign_window_widget.h"
48 52
49 #if defined(OS_CHROMEOS) 53 #if defined(OS_CHROMEOS)
50 #include "base/chromeos/chromeos_version.h" 54 #include "base/chromeos/chromeos_version.h"
51 #endif 55 #endif
52 56
53 using std::max; 57 using std::max;
54 using std::min; 58 using std::min;
55 59
56 namespace aura { 60 namespace wm {
57 61
58 namespace { 62 namespace {
59 63
60 // Standard Linux mouse buttons for going back and forward. 64 // Standard Linux mouse buttons for going back and forward.
61 const int kBackMouseButton = 8; 65 const int kBackMouseButton = 8;
62 const int kForwardMouseButton = 9; 66 const int kForwardMouseButton = 9;
63 67
64 // These are the same values that are used to calibrate touch events in 68 // These are the same values that are used to calibrate touch events in
65 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc). 69 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc).
66 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605) 70 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605)
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 case ui::VKEY_OEM_PLUS: 166 case ui::VKEY_OEM_PLUS:
163 case ui::VKEY_OEM_COMMA: 167 case ui::VKEY_OEM_COMMA:
164 case ui::VKEY_OEM_MINUS: 168 case ui::VKEY_OEM_MINUS:
165 case ui::VKEY_OEM_PERIOD: 169 case ui::VKEY_OEM_PERIOD:
166 return true; 170 return true;
167 default: 171 default:
168 return false; 172 return false;
169 } 173 }
170 } 174 }
171 175
176 unsigned InitWindowChanges(const gfx::Rect& bounds,
177 ::Window sibling_to_stack_above,
178 XWindowChanges& wc) {
179 wc.x = bounds.x();
180 wc.y = bounds.y();
181 wc.width = bounds.width();
182 wc.height = bounds.height();
183 if (!sibling_to_stack_above) {
184 wc.stack_mode = Below;
185 return CWX | CWY | CWWidth | CWHeight | CWStackMode;
186 }
187
188 wc.sibling = sibling_to_stack_above;
189 wc.stack_mode = Above;
190 return CWX | CWY | CWWidth | CWHeight | CWStackMode | CWSibling;
191 }
192
193 aura::Window* FindLowestCommonAncestor(
194 aura::Window* root, const aura::Window* p, const aura::Window* q) {
195 // Root is the LCA.
196 if (root == p || root == q)
197 return root;
198
199 aura::Window* prev = NULL;
200 const aura::Window::Windows& children = root->children();
201 for (size_t i = 0; i < children.size(); ++i) {
202 // Try to find LCA of p and q in subtree.
203 aura::Window* next = FindLowestCommonAncestor(children[i], p, q);
204 if (next) {
205 // If a LCA was previously found, p and q must be in different subtrees.
206 if (prev)
207 return root;
208
209 prev = next;
210 }
211 }
212
213 return prev;
214 }
215
216 gfx::Vector2d GetTargetOffsetInRootWindow(const aura::Window* window) {
217 gfx::Vector2d offset;
218
219 const aura::Window* p = window;
220 for (; p != window->GetRootWindow(); p = p->parent())
221 offset += p->GetTargetBounds().OffsetFromOrigin();
222
223 return offset;
224 }
225
226 gfx::Rect GetTargetBoundsInRootWindow(const aura::Window* window) {
227 return gfx::Rect(window->GetTargetBounds().size()) +
228 GetTargetOffsetInRootWindow(window);
danakj 2013/02/22 21:42:59 Yep looks good!
229 }
230
172 } // namespace 231 } // namespace
173 232
174 namespace internal { 233 namespace internal {
175 234
176 // A very lightweight message-pump observer that routes all the touch events to 235 // A very lightweight message-pump observer that routes all the touch events to
177 // the X root window so that they can be calibrated properly. 236 // the X root window so that they can be calibrated properly.
178 class TouchEventCalibrate : public base::MessagePumpObserver { 237 class TouchEventCalibrate : public base::MessagePumpObserver {
179 public: 238 public:
180 TouchEventCalibrate() { 239 TouchEventCalibrate() {
181 MessageLoopForUI::current()->AddObserver(this); 240 MessageLoopForUI::current()->AddObserver(this);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 : delegate_(NULL), 318 : delegate_(NULL),
260 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()), 319 xdisplay_(base::MessagePumpAuraX11::GetDefaultXDisplay()),
261 xwindow_(0), 320 xwindow_(0),
262 x_root_window_(DefaultRootWindow(xdisplay_)), 321 x_root_window_(DefaultRootWindow(xdisplay_)),
263 current_cursor_(ui::kCursorNull), 322 current_cursor_(ui::kCursorNull),
264 window_mapped_(false), 323 window_mapped_(false),
265 bounds_(bounds), 324 bounds_(bounds),
266 focus_when_shown_(false), 325 focus_when_shown_(false),
267 touch_calibrate_(new internal::TouchEventCalibrate), 326 touch_calibrate_(new internal::TouchEventCalibrate),
268 mouse_move_filter_(new MouseMoveFilter), 327 mouse_move_filter_(new MouseMoveFilter),
269 atom_cache_(xdisplay_, kAtomsToCache) { 328 atom_cache_(xdisplay_, kAtomsToCache),
329 configure_window_(NULL),
330 x_input_window_(0),
331 need_to_set_default_cursor_(true) {
270 XSetWindowAttributes swa; 332 XSetWindowAttributes swa;
271 memset(&swa, 0, sizeof(swa)); 333 memset(&swa, 0, sizeof(swa));
272 swa.background_pixmap = None; 334 swa.background_pixmap = None;
273 xwindow_ = XCreateWindow( 335 xwindow_ = XCreateWindow(
274 xdisplay_, x_root_window_, 336 xdisplay_, x_root_window_,
275 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 337 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
276 0, // border width 338 0, // border width
277 CopyFromParent, // depth 339 CopyFromParent, // depth
278 InputOutput, 340 InputOutput,
279 CopyFromParent, // visual 341 CopyFromParent, // visual
280 CWBackPixmap, 342 CWBackPixmap,
281 &swa); 343 &swa);
344 x_input_window_ = XCreateWindow(
345 xdisplay_, xwindow_,
346 -100, -100, 1, 1,
347 0, // border width
348 CopyFromParent, // depth
349 InputOnly,
350 CopyFromParent, // visual
351 0,
352 NULL);
353 XMapWindow(xdisplay_, x_input_window_);
354 XCompositeRedirectSubwindows(xdisplay_, xwindow_, CompositeRedirectManual);
355
282 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); 356 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
283 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this); 357 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this);
284 358
285 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | 359 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
286 KeyPressMask | KeyReleaseMask | 360 KeyPressMask | KeyReleaseMask |
287 EnterWindowMask | LeaveWindowMask | 361 EnterWindowMask | LeaveWindowMask |
288 ExposureMask | VisibilityChangeMask | 362 ExposureMask | VisibilityChangeMask |
289 StructureNotifyMask | PropertyChangeMask | 363 StructureNotifyMask | PropertyChangeMask |
290 PointerMotionMask; 364 PointerMotionMask |
365 SubstructureNotifyMask | SubstructureRedirectMask;
291 XSelectInput(xdisplay_, xwindow_, event_mask); 366 XSelectInput(xdisplay_, xwindow_, event_mask);
292 XFlush(xdisplay_); 367 XFlush(xdisplay_);
293 368
294 if (base::MessagePumpForUI::HasXInput2()) 369 if (base::MessagePumpForUI::HasXInput2())
295 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 370 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
296 371
297 SelectEventsForRootWindow(); 372 SelectEventsForRootWindow();
298 373
299 // Get the initial size of the X root window. 374 // Get the initial size of the X root window.
300 XWindowAttributes attrs; 375 XWindowAttributes attrs;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 XRRSelectInput(xdisplay_, x_root_window_, 408 XRRSelectInput(xdisplay_, x_root_window_,
334 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); 409 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
335 } 410 }
336 411
337 RootWindowHostLinux::~RootWindowHostLinux() { 412 RootWindowHostLinux::~RootWindowHostLinux() {
338 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this); 413 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this);
339 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 414 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
340 415
341 UnConfineCursor(); 416 UnConfineCursor();
342 417
418 GetRootWindow()->RemoveObserver(this);
419 XDestroyWindow(xdisplay_, x_input_window_);
343 XDestroyWindow(xdisplay_, xwindow_); 420 XDestroyWindow(xdisplay_, xwindow_);
344 } 421 }
345 422
346 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { 423 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) {
347 XEvent* xev = event; 424 XEvent* xev = event;
348 425
349 if (FindEventTarget(event) == x_root_window_) 426 if (FindEventTarget(event) == x_root_window_)
350 return DispatchEventForRootWindow(event); 427 return DispatchEventForRootWindow(event);
351 428
352 switch (xev->type) { 429 switch (xev->type) {
430 case ConfigureNotify: {
431 if (event->xconfigure.window == x_input_window_)
432 return true;
433
434 ForeignWindowMap::iterator it = foreign_windows_.find(
435 event->xconfigure.window);
436 if (it != foreign_windows_.end()) {
437 ForeignWindow* window = it->second;
438
439 int border_size = event->xconfigure.border_width * 2;
440 gfx::Size size(event->xconfigure.width + border_size,
441 event->xconfigure.height + border_size);
442 window->OnWindowSizeChanged(size);
443 return true;
444 }
445 break;
446 }
447 case MapNotify: {
448 ForeignWindowMap::iterator it = foreign_windows_.find(
449 event->xmap.window);
450 if (it != foreign_windows_.end()) {
451 ForeignWindow* window = it->second;
452
453 window->OnWindowVisibilityChanged(true);
454 return true;
455 }
456 break;
457 }
458 case UnmapNotify: {
459 ForeignWindowMap::iterator it = foreign_windows_.find(
460 event->xunmap.window);
461 if (it != foreign_windows_.end()) {
462 ForeignWindow* window = it->second;
463
464 // Hide top level widget.
465 views::Widget* widget = window->GetWidget();
466 widget->Hide();
467
468 window->OnWindowVisibilityChanged(false);
469 return true;
470 }
471 break;
472 }
473 case CreateNotify: {
474 int border_size = event->xcreatewindow.border_width * 2;
475 gfx::Size size(event->xcreatewindow.width + border_size,
476 event->xcreatewindow.height + border_size);
477
478 // Create a foreign window for this X window.
479 ForeignWindow::CreateParams params(event->xcreatewindow.window, size);
480 scoped_refptr<ForeignWindow> window(new ForeignWindow(params));
481
482 // Create top level window widget.
483 ForeignWindowWidget::CreateWindow(window.get());
484
485 // Add foreign window to map.
486 foreign_windows_[event->xcreatewindow.window] = window.get();
487 return true;
488 }
489 case DestroyNotify: {
490 ForeignWindowMap::iterator it = foreign_windows_.find(
491 event->xdestroywindow.window);
492 if (it != foreign_windows_.end()) {
493 ForeignWindow* window = it->second;
494
495 // Tell foreign window that X window has been destroyed.
496 window->OnWindowDestroyed();
497
498 // Close top level widget.
499 views::Widget* widget = window->GetWidget();
500 widget->Close();
501
502 foreign_windows_.erase(it);
503 }
504 return true;
505 }
506 case MapRequest: {
507 ForeignWindowMap::iterator it = foreign_windows_.find(
508 event->xmaprequest.window);
509 if (it != foreign_windows_.end()) {
510 ForeignWindow* window = it->second;
511
512 // Show top level widget.
513 views::Widget* widget = window->GetWidget();
514 widget->Show();
515 }
516 return true;
517 }
518 case ConfigureRequest: {
519 // TODO(reveman): Respect ConfigureRequest events.
520 return true;
521 }
522 case CirculateRequest: {
523 // TODO(reveman): Respect CirculateRequest events.
524 return true;
525 }
526 }
527
528 switch (xev->type) {
353 case EnterNotify: { 529 case EnterNotify: {
354 ui::MouseEvent mouseenter_event(xev); 530 ui::MouseEvent mouseenter_event(xev);
355 TranslateAndDispatchMouseEvent(&mouseenter_event); 531 TranslateAndDispatchMouseEvent(&mouseenter_event);
356 break; 532 break;
357 } 533 }
358 case Expose: 534 case Expose:
359 delegate_->AsRootWindow()->ScheduleFullDraw(); 535 delegate_->AsRootWindow()->ScheduleFullDraw();
360 break; 536 break;
361 case KeyPress: { 537 case KeyPress: {
362 ui::KeyEvent keydown_event(xev, false); 538 ui::KeyEvent keydown_event(xev, false);
363 delegate_->OnHostKeyEvent(&keydown_event); 539 delegate_->OnHostKeyEvent(&keydown_event);
364 break; 540 break;
365 } 541 }
366 case KeyRelease: { 542 case KeyRelease: {
367 ui::KeyEvent keyup_event(xev, false); 543 ui::KeyEvent keyup_event(xev, false);
368 delegate_->OnHostKeyEvent(&keyup_event); 544 delegate_->OnHostKeyEvent(&keyup_event);
369 break; 545 break;
370 } 546 }
371 case ButtonPress: { 547 case ButtonPress: {
372 if (static_cast<int>(xev->xbutton.button) == kBackMouseButton || 548 if (static_cast<int>(xev->xbutton.button) == kBackMouseButton ||
373 static_cast<int>(xev->xbutton.button) == kForwardMouseButton) { 549 static_cast<int>(xev->xbutton.button) == kForwardMouseButton) {
374 client::UserActionClient* gesture_client = 550 aura::client::UserActionClient* gesture_client =
375 client::GetUserActionClient(delegate_->AsRootWindow()); 551 aura::client::GetUserActionClient(delegate_->AsRootWindow());
376 if (gesture_client) { 552 if (gesture_client) {
377 gesture_client->OnUserAction( 553 gesture_client->OnUserAction(
378 static_cast<int>(xev->xbutton.button) == kBackMouseButton ? 554 static_cast<int>(xev->xbutton.button) == kBackMouseButton ?
379 client::UserActionClient::BACK : 555 aura::client::UserActionClient::BACK :
380 client::UserActionClient::FORWARD); 556 aura::client::UserActionClient::FORWARD);
381 } 557 }
382 break; 558 break;
383 } 559 }
384 } // fallthrough 560 } // fallthrough
385 case ButtonRelease: { 561 case ButtonRelease: {
386 ui::MouseEvent mouseev(xev); 562 ui::MouseEvent mouseev(xev);
387 TranslateAndDispatchMouseEvent(&mouseev); 563 TranslateAndDispatchMouseEvent(&mouseev);
388 break; 564 break;
389 } 565 }
390 case FocusOut: 566 case FocusOut:
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 652 }
477 653
478 ui::MouseEvent mouseev(xev); 654 ui::MouseEvent mouseev(xev);
479 TranslateAndDispatchMouseEvent(&mouseev); 655 TranslateAndDispatchMouseEvent(&mouseev);
480 break; 656 break;
481 } 657 }
482 } 658 }
483 return true; 659 return true;
484 } 660 }
485 661
486 void RootWindowHostLinux::SetDelegate(RootWindowHostDelegate* delegate) { 662 void RootWindowHostLinux::OnWindowAdded(aura::Window* window) {
663 window->AddObserver(this);
664 }
665
666 void RootWindowHostLinux::OnWillRemoveWindow(aura::Window* window) {
667 if (configure_window_ == window)
668 configure_window_ = window->parent();
669
670 window->RemoveObserver(this);
671 }
672
673 void RootWindowHostLinux::OnWindowStackingChanged(aura::Window* window) {
674 ScheduleConfigure(GetRootWindow());
675 }
676
677 void RootWindowHostLinux::OnWindowVisibilityChanged(
678 aura::Window* window, bool visible) {
679 ScheduleConfigure(GetRootWindow());
680 }
681
682 void RootWindowHostLinux::OnWindowBoundsChanged(
683 aura::Window* window,
684 const gfx::Rect& old_bounds,
685 const gfx::Rect& new_bounds) {
686 ScheduleConfigure(GetRootWindow());
687 }
688
689 void RootWindowHostLinux::OnWindowDestroying(aura::Window* window) {
690 window->RemoveObserver(this);
691 }
692
693 ::Window RootWindowHostLinux::GetTopForeignWindow(const aura::Window* window) {
694 // children are ordered back to front, so walk through it in reverse.
695 const aura::Window::Windows& children = window->children();
696 for (size_t i = children.size(); i; --i) {
697 ::Window top = GetTopForeignWindow(children[i - 1]);
698 if (top)
699 return top;
700 }
701
702 ForeignWindow* foreign_window = ForeignWindow::GetForeignWindowForNativeView(
703 const_cast<gfx::NativeView>(window));
704 if (foreign_window) {
705 // Ignore windows that we're not allowed to configure.
706 if (foreign_window->IsManaged())
707 return foreign_window->GetWindowHandle();
708 }
709
710 return 0;
711 }
712
713 ::Window RootWindowHostLinux::FindForeignWindowToStackAbove(
714 const aura::Window* window) {
715 const aura::Window* parent = window->parent();
716 if (!parent)
717 return 0;
718
719 ::Window above = 0;
720
721 const aura::Window::Windows& children = parent->children();
722 for (size_t i = 0; i < children.size(); ++i) {
723 if (children[i] == window)
724 break;
725
726 ::Window top = GetTopForeignWindow(children[i]);
727 if (top)
728 above = top;
729 }
730
731 if (!above)
732 above = FindForeignWindowToStackAbove(parent);
733
734 return above;
735 }
736
737 void RootWindowHostLinux::MapWindowIfNeeded(ForeignWindow* window) {
738 ForeignWindow::DisplayState current_display_state =
739 window->GetDisplayState();
740
741 if (current_display_state != ForeignWindow::DISPLAY_NORMAL) {
742 // TODO(reveman): Ignore possible X error.
743 XMapWindow(xdisplay_, window->GetWindowHandle());
744
745 window->SetDisplayState(ForeignWindow::DISPLAY_NORMAL);
746 }
747 }
748
749 void RootWindowHostLinux::UnmapWindowIfNeeded(ForeignWindow* window) {
750 ForeignWindow::DisplayState current_display_state =
751 window->GetDisplayState();
752
753 if (current_display_state == ForeignWindow::DISPLAY_NORMAL) {
754 // TODO(reveman): Ignore possible X error.
755 XUnmapWindow(xdisplay_, window->GetWindowHandle());
756
757 window->SetDisplayState(ForeignWindow::DISPLAY_ICONIC);
758 }
759 }
760
761 void RootWindowHostLinux::RecursiveConfigure(
762 aura::Window* window,
763 gfx::Vector2d offset,
764 ::Window* sibling_to_stack_above,
765 SkRegion* input_region) {
766 gfx::Rect bounds(gfx::Rect(window->GetTargetBounds().size()) + offset);
767 SkRegion::Op input_region_op;
768
769 ForeignWindow* foreign_window = ForeignWindow::GetForeignWindowForNativeView(
770 const_cast<gfx::NativeView>(window));
771 if (foreign_window) {
772 DCHECK(!bounds.IsEmpty());
773
774 // We should only be adjusting attributes of managed windows.
775 if (foreign_window->IsManaged()) {
776 if (!window->IsVisible())
777 UnmapWindowIfNeeded(foreign_window);
778
779 XWindowChanges wc;
780 unsigned mask = InitWindowChanges(bounds, *sibling_to_stack_above, wc);
781 // Get rid of any borders.
782 wc.border_width = 0;
783 mask |= CWBorderWidth;
784 // TODO(reveman): Ignore possible X error.
785 XConfigureWindow(xdisplay_,
786 foreign_window->GetWindowHandle(),
787 mask,
788 &wc);
789
790 *sibling_to_stack_above = foreign_window->GetWindowHandle();
791
792 if (window->IsVisible())
793 MapWindowIfNeeded(foreign_window);
794 }
795
796 // Remove foreign window bounds from input region.
797 bounds.Inset(window->hit_test_bounds_override_inner());
798 input_region_op = SkRegion::kDifference_Op;
799 } else {
800 // Add window bounds to output region.
801 bounds.Inset(window->hit_test_bounds_override_outer_mouse());
802 input_region_op = SkRegion::kUnion_Op;
803 }
804
805 if (window->delegate() && window->IsVisible()) {
806 input_region->op(bounds.x(),
807 bounds.y(),
808 bounds.right(),
809 bounds.bottom(),
810 input_region_op);
811 }
812
813 const aura::Window::Windows& children = window->children();
814 for (size_t i = 0; i < children.size(); ++i) {
815 RecursiveConfigure(
816 children[i],
817 offset + children[i]->GetTargetBounds().OffsetFromOrigin(),
818 sibling_to_stack_above,
819 input_region);
820 }
821 }
822
823 void RootWindowHostLinux::Configure() {
824 if (!configure_window_)
825 return;
826
827 SkRegion input_region;
828 ::Window sibling_to_stack_above =
829 FindForeignWindowToStackAbove(configure_window_);
830 RecursiveConfigure(configure_window_,
831 GetTargetOffsetInRootWindow(configure_window_),
832 &sibling_to_stack_above,
833 &input_region);
834
835 // Update input window and set focus when we configure the root window.
836 if (configure_window_ == GetRootWindow()) {
837 // Configure input window above all other windows.
838 XWindowChanges wc;
839 gfx::Rect bounds(gfx::Point(0, 0), bounds_.size());
840 unsigned mask = InitWindowChanges(bounds, sibling_to_stack_above, wc);
841 XConfigureWindow(xdisplay_, x_input_window_, mask, &wc);
842
843 // Update input window shape.
844 std::vector<XRectangle> rectangles;
845 for (SkRegion::Iterator iter(input_region); !iter.done(); iter.next()) {
846 const SkIRect& sk_rect = iter.rect();
847 XRectangle x_rect;
848 x_rect.x = sk_rect.x();
849 x_rect.y = sk_rect.y();
850 x_rect.width = sk_rect.width();
851 x_rect.height = sk_rect.height();
852 rectangles.push_back(x_rect);
853 }
854
855 XShapeCombineRectangles(xdisplay_,
856 x_input_window_,
857 ShapeInput,
858 0,
859 0,
860 &rectangles.front(),
861 rectangles.size(),
862 ShapeSet,
863 Unsorted);
864 }
865
866 XFlush(xdisplay_);
867 configure_window_ = NULL;
868 }
869
870 void RootWindowHostLinux::ScheduleConfigure(aura::Window* window) {
871 if (!configure_window_) {
872 configure_window_ = window;
873 MessageLoop::current()->PostTask(
874 FROM_HERE,
875 base::Bind(&RootWindowHostLinux::Configure, AsWeakPtr()));
876 } else {
877 configure_window_ = FindLowestCommonAncestor(
878 GetRootWindow(), configure_window_, window);
879 }
880 }
881
882 void RootWindowHostLinux::SetDelegate(aura::RootWindowHostDelegate* delegate) {
883 DCHECK(!delegate_);
487 delegate_ = delegate; 884 delegate_ = delegate;
488 } 885 DCHECK(delegate_);
489 886 delegate_->AsRootWindow()->AddObserver(this);
490 RootWindow* RootWindowHostLinux::GetRootWindow() { 887 ScheduleConfigure(delegate_->AsRootWindow());
888 }
889
890 aura::RootWindow* RootWindowHostLinux::GetRootWindow() {
491 return delegate_->AsRootWindow(); 891 return delegate_->AsRootWindow();
492 } 892 }
493 893
494 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { 894 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() {
495 return xwindow_; 895 return xwindow_;
496 } 896 }
497 897
498 void RootWindowHostLinux::Show() { 898 void RootWindowHostLinux::Show() {
499 if (!window_mapped_) { 899 if (!window_mapped_) {
500 // Before we map the window, set size hints. Otherwise, some window managers 900 // Before we map the window, set size hints. Otherwise, some window managers
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } 987 }
588 988
589 void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) { 989 void RootWindowHostLinux::SetCursor(gfx::NativeCursor cursor) {
590 if (cursor == current_cursor_) 990 if (cursor == current_cursor_)
591 return; 991 return;
592 current_cursor_ = cursor; 992 current_cursor_ = cursor;
593 SetCursorInternal(cursor); 993 SetCursorInternal(cursor);
594 } 994 }
595 995
596 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) { 996 bool RootWindowHostLinux::QueryMouseLocation(gfx::Point* location_return) {
597 client::CursorClient* cursor_client = 997 aura::client::CursorClient* cursor_client =
598 client::GetCursorClient(GetRootWindow()); 998 aura::client::GetCursorClient(GetRootWindow());
599 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) { 999 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) {
600 *location_return = gfx::Point(0, 0); 1000 *location_return = gfx::Point(0, 0);
601 return false; 1001 return false;
602 } 1002 }
603 1003
604 ::Window root_return, child_return; 1004 ::Window root_return, child_return;
605 int root_x_return, root_y_return, win_x_return, win_y_return; 1005 int root_x_return, root_y_return, win_x_return, win_y_return;
606 unsigned int mask_return; 1006 unsigned int mask_return;
607 XQueryPointer(xdisplay_, 1007 XQueryPointer(xdisplay_,
608 xwindow_, 1008 xwindow_,
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 if (mouse_move_filter_ && mouse_move_filter_->Filter(xev)) 1310 if (mouse_move_filter_ && mouse_move_filter_->Filter(xev))
911 break; 1311 break;
912 } else if (type == ui::ET_MOUSE_PRESSED || 1312 } else if (type == ui::ET_MOUSE_PRESSED ||
913 type == ui::ET_MOUSE_RELEASED) { 1313 type == ui::ET_MOUSE_RELEASED) {
914 XIDeviceEvent* xievent = 1314 XIDeviceEvent* xievent =
915 static_cast<XIDeviceEvent*>(xev->xcookie.data); 1315 static_cast<XIDeviceEvent*>(xev->xcookie.data);
916 int button = xievent->detail; 1316 int button = xievent->detail;
917 if (button == kBackMouseButton || button == kForwardMouseButton) { 1317 if (button == kBackMouseButton || button == kForwardMouseButton) {
918 if (type == ui::ET_MOUSE_RELEASED) 1318 if (type == ui::ET_MOUSE_RELEASED)
919 break; 1319 break;
920 client::UserActionClient* gesture_client = 1320 aura::client::UserActionClient* gesture_client =
921 client::GetUserActionClient(delegate_->AsRootWindow()); 1321 aura::client::GetUserActionClient(delegate_->AsRootWindow());
922 if (gesture_client) { 1322 if (gesture_client) {
923 bool reverse_direction = 1323 bool reverse_direction =
924 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); 1324 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled();
925 gesture_client->OnUserAction( 1325 gesture_client->OnUserAction(
926 (button == kBackMouseButton && !reverse_direction) || 1326 (button == kBackMouseButton && !reverse_direction) ||
927 (button == kForwardMouseButton && reverse_direction) ? 1327 (button == kForwardMouseButton && reverse_direction) ?
928 client::UserActionClient::BACK : 1328 aura::client::UserActionClient::BACK :
929 client::UserActionClient::FORWARD); 1329 aura::client::UserActionClient::FORWARD);
930 } 1330 }
931 break; 1331 break;
932 } 1332 }
933 } 1333 }
934 ui::MouseEvent mouseev(xev); 1334 ui::MouseEvent mouseev(xev);
935 TranslateAndDispatchMouseEvent(&mouseev); 1335 TranslateAndDispatchMouseEvent(&mouseev);
936 break; 1336 break;
937 } 1337 }
938 case ui::ET_MOUSEWHEEL: { 1338 case ui::ET_MOUSEWHEEL: {
939 ui::MouseWheelEvent mouseev(xev); 1339 ui::MouseWheelEvent mouseev(xev);
(...skipping 19 matching lines...) Expand all
959 } 1359 }
960 1360
961 bool RootWindowHostLinux::IsWindowManagerPresent() { 1361 bool RootWindowHostLinux::IsWindowManagerPresent() {
962 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership 1362 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
963 // of WM_Sn selections (where n is a screen number). 1363 // of WM_Sn selections (where n is a screen number).
964 return XGetSelectionOwner( 1364 return XGetSelectionOwner(
965 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None; 1365 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
966 } 1366 }
967 1367
968 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { 1368 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) {
969 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); 1369 XDefineCursor(xdisplay_, x_input_window_, cursor.platform());
1370
1371 // Set default native window cursor.
1372 if (need_to_set_default_cursor_ && cursor.native_type() == ui::kCursorNull) {
1373 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
1374 need_to_set_default_cursor_ = false;
1375 }
970 } 1376 }
971 1377
972 void RootWindowHostLinux::TranslateAndDispatchMouseEvent( 1378 void RootWindowHostLinux::TranslateAndDispatchMouseEvent(
973 ui::MouseEvent* event) { 1379 ui::MouseEvent* event) {
974 RootWindow* root = GetRootWindow(); 1380 aura::RootWindow* root = GetRootWindow();
975 client::ScreenPositionClient* screen_position_client = 1381 aura::client::ScreenPositionClient* screen_position_client =
976 GetScreenPositionClient(root); 1382 GetScreenPositionClient(root);
977 if (screen_position_client && !bounds_.Contains(event->location())) { 1383 if (screen_position_client && !bounds_.Contains(event->location())) {
978 gfx::Point location(event->location()); 1384 gfx::Point location(event->location());
979 screen_position_client->ConvertNativePointToScreen(root, &location); 1385 screen_position_client->ConvertNativePointToScreen(root, &location);
980 screen_position_client->ConvertPointFromScreen(root, &location); 1386 screen_position_client->ConvertPointFromScreen(root, &location);
981 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to 1387 // |delegate_|'s OnHoustMouseEvent expects native coordinates relative to
982 // root. 1388 // root.
983 location = ui::ConvertPointToPixel(root->layer(), location); 1389 location = ui::ConvertPointToPixel(root->layer(), location);
984 event->set_location(location); 1390 event->set_location(location);
985 event->set_root_location(location); 1391 event->set_root_location(location);
986 } 1392 }
987 delegate_->OnHostMouseEvent(event); 1393 delegate_->OnHostMouseEvent(event);
988 } 1394 }
989 1395
990 scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage( 1396 scoped_ptr<ui::XScopedImage> RootWindowHostLinux::GetXImage(
991 const gfx::Rect& snapshot_bounds) { 1397 const gfx::Rect& snapshot_bounds) {
992 scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage( 1398 scoped_ptr<ui::XScopedImage> image(new ui::XScopedImage(
993 XGetImage(xdisplay_, xwindow_, 1399 XGetImage(xdisplay_, xwindow_,
994 snapshot_bounds.x(), snapshot_bounds.y(), 1400 snapshot_bounds.x(), snapshot_bounds.y(),
995 snapshot_bounds.width(), snapshot_bounds.height(), 1401 snapshot_bounds.width(), snapshot_bounds.height(),
996 AllPlanes, ZPixmap))); 1402 AllPlanes, ZPixmap)));
997 if (!image->get()) { 1403 if (!image->get()) {
998 LOG(ERROR) << "XGetImage failed"; 1404 LOG(ERROR) << "XGetImage failed";
999 image.reset(); 1405 image.reset();
1000 } 1406 }
1001 return image.Pass(); 1407 return image.Pass();
1002 } 1408 }
1003 1409
1004 // static 1410 } // namespace wm
1005 RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
1006 return new RootWindowHostLinux(bounds);
1007 }
1008
1009 // static
1010 gfx::Size RootWindowHost::GetNativeScreenSize() {
1011 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay();
1012 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
1013 }
1014
1015 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698