Chromium Code Reviews| Index: ui/aura/desktop_host_linux.cc |
| diff --git a/ui/aura/desktop_host_linux.cc b/ui/aura/desktop_host_linux.cc |
| index ed47ca21dad976628412990014f2c581be1e0b07..0cf0db06f86ce4e2fd8393ddd19d735a1102cd7b 100644 |
| --- a/ui/aura/desktop_host_linux.cc |
| +++ b/ui/aura/desktop_host_linux.cc |
| @@ -198,7 +198,12 @@ class DesktopHostLinux : public DesktopHost { |
| virtual void SetCursor(gfx::NativeCursor cursor_type) OVERRIDE; |
| virtual gfx::Point QueryMouseLocation() OVERRIDE; |
| - // Returns true if there's an X window manager present. |
| + // Handle notification from the X server that |xwindow_| has been resized. |
| + void HandleConfigureNotify(const gfx::Size& new_size); |
| + |
| + // Returns true if there's an X window manager present... in most cases. Some |
| + // window managers (notably, ion3) don't implement enough of ICCCM for us to |
| + // detect that they're there. |
| bool IsWindowManagerPresent(); |
| Desktop* desktop_; |
| @@ -211,7 +216,7 @@ class DesktopHostLinux : public DesktopHost { |
| gfx::NativeCursor current_cursor_; |
| // The size of |xwindow_|. |
| - gfx::Rect bounds_; |
| + gfx::Size size_; |
|
Daniel Erat
2011/10/21 23:00:37
using a Rect here didn't make sense; we never need
sadrul
2011/10/22 18:53:04
Nice
|
| DISALLOW_COPY_AND_ASSIGN(DesktopHostLinux); |
| }; |
| @@ -221,19 +226,22 @@ DesktopHostLinux::DesktopHostLinux(const gfx::Rect& bounds) |
| xdisplay_(NULL), |
| xwindow_(0), |
| current_cursor_(aura::kCursorNull), |
| - bounds_(bounds) { |
| + size_(bounds.size()) { |
| // This assumes that the message-pump creates and owns the display. |
| xdisplay_ = base::MessagePumpX::GetDefaultXDisplay(); |
| // Ingore the requested bounds and just cover the whole screen if there's no |
| // X window manager present. |
| - if (!IsWindowManagerPresent()) |
| - bounds_.SetRect( |
| + gfx::Rect actual_bounds = bounds; |
| + if (!IsWindowManagerPresent()) { |
| + actual_bounds.SetRect( |
| 0, 0, DisplayWidth(xdisplay_, 0), DisplayHeight(xdisplay_, 0)); |
|
sadrul
2011/10/22 18:53:04
I was thinking about this change ... perhaps we ar
Daniel Erat
2011/10/23 04:02:55
Yeah, I wasn't entirely convinced about this part.
sadrul
2011/10/23 20:45:02
I was thinking perhaps we can always to this for c
|
| + size_ = actual_bounds.size(); |
| + } |
| xwindow_ = XCreateSimpleWindow(xdisplay_, DefaultRootWindow(xdisplay_), |
| - bounds_.x(), bounds_.y(), |
| - bounds_.width(), bounds_.height(), |
| + actual_bounds.x(), actual_bounds.y(), |
| + actual_bounds.width(), actual_bounds.height(), |
| 0, 0, 0); |
| long event_mask = ButtonPressMask | ButtonReleaseMask | |
| @@ -308,10 +316,8 @@ base::MessagePumpDispatcher::DispatchStatus DesktopHostLinux::Dispatch( |
| // It's possible that the X window may be resized by some other means than |
| // from within aura (e.g. the X window manager can change the size). Make |
| // sure the desktop size is maintained properly. |
| - gfx::Size size(xev->xconfigure.width, xev->xconfigure.height); |
| - if (bounds_.size() != size) |
| - bounds_.set_size(size); |
| - desktop_->OnHostResized(size); |
| + HandleConfigureNotify( |
| + gfx::Size(xev->xconfigure.width, xev->xconfigure.height)); |
| handled = true; |
| break; |
| } |
| @@ -377,25 +383,38 @@ gfx::AcceleratedWidget DesktopHostLinux::GetAcceleratedWidget() { |
| void DesktopHostLinux::Show() { |
| XMapWindow(xdisplay_, xwindow_); |
| + // Wait for notification that the window is mapped, which happens |
| + // asynchronously if there's a window manager running. |
| + gfx::Size new_size = size_; |
| + while (true) { |
| + XEvent event; |
| + XWindowEvent(xdisplay_, xwindow_, StructureNotifyMask, &event); |
| + if (event.type == ConfigureNotify) |
| + new_size.SetSize(event.xconfigure.width, event.xconfigure.height); |
| + else if (event.type == MapNotify) |
| + break; |
| + } |
| + |
| // If there's no window manager running, we need to assign the X input focus |
| - // to our host window. (If there's no window manager running, it should also |
| - // be safe to assume that the host window will have been mapped by the time |
| - // that our SetInputFocus request is received.) |
| - if (!IsWindowManagerPresent()) |
| + // to our host window. |
| + if (!IsWindowManagerPresent()) { |
| XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); |
|
sadrul
2011/10/22 18:53:04
How about we just XMapWindow+XFlush here and retur
Daniel Erat
2011/10/23 04:02:55
Thanks, I like this more as well. Sounds fine, as
|
| + XFlush(xdisplay_); |
| + } |
| - XFlush(xdisplay_); |
| + // If we removed any ConfigureNotify events from the queue, make sure that we |
| + // apply size changes mentioned in them. |
| + if (new_size != size_) |
| + HandleConfigureNotify(new_size); |
| } |
| gfx::Size DesktopHostLinux::GetSize() const { |
| - return bounds_.size(); |
| + return size_; |
| } |
| void DesktopHostLinux::SetSize(const gfx::Size& size) { |
| - if (bounds_.size() == size) |
| - return; |
| - bounds_.set_size(size); |
| - XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); |
| + if (size_ != size) |
| + XResizeWindow(xdisplay_, xwindow_, size.width(), size.height()); |
| } |
| void DesktopHostLinux::SetCursor(gfx::NativeCursor cursor) { |
| @@ -421,8 +440,14 @@ gfx::Point DesktopHostLinux::QueryMouseLocation() { |
| &root_x_return, &root_y_return, |
| &win_x_return, &win_y_return, |
| &mask_return); |
| - return gfx::Point(max(0, min(bounds_.width(), win_x_return)), |
| - max(0, min(bounds_.height(), win_y_return))); |
| + return gfx::Point(max(0, min(size_.width(), win_x_return)), |
| + max(0, min(size_.height(), win_y_return))); |
| +} |
| + |
| +void DesktopHostLinux::HandleConfigureNotify(const gfx::Size& size) { |
| + if (size_ != size) |
| + size_ = size; |
| + desktop_->OnHostResized(size); |
| } |
| bool DesktopHostLinux::IsWindowManagerPresent() { |