Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/exo/pointer.h" | 5 #include "components/exo/pointer.h" |
| 6 | 6 |
| 7 #include "ash/public/cpp/shell_window_ids.h" | 7 #include "ash/public/cpp/shell_window_ids.h" |
| 8 #include "cc/output/copy_output_request.h" | 8 #include "cc/output/copy_output_request.h" |
| 9 #include "cc/output/copy_output_result.h" | 9 #include "cc/output/copy_output_result.h" |
| 10 #include "components/exo/pointer_delegate.h" | 10 #include "components/exo/pointer_delegate.h" |
| 11 #include "components/exo/pointer_stylus_delegate.h" | 11 #include "components/exo/pointer_stylus_delegate.h" |
| 12 #include "components/exo/surface.h" | 12 #include "components/exo/surface.h" |
| 13 #include "components/exo/wm_helper.h" | 13 #include "components/exo/wm_helper.h" |
| 14 #include "ui/aura/client/cursor_client.h" | 14 #include "ui/aura/client/cursor_client.h" |
| 15 #include "ui/aura/env.h" | 15 #include "ui/aura/env.h" |
| 16 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
| 17 #include "ui/display/manager/display_manager.h" | 17 #include "ui/display/manager/display_manager.h" |
| 18 #include "ui/display/manager/managed_display_info.h" | 18 #include "ui/display/manager/managed_display_info.h" |
| 19 #include "ui/display/screen.h" | 19 #include "ui/display/screen.h" |
| 20 #include "ui/events/event.h" | 20 #include "ui/events/event.h" |
| 21 #include "ui/gfx/geometry/vector2d_conversions.h" | 21 #include "ui/gfx/geometry/vector2d_conversions.h" |
| 22 #include "ui/gfx/transform_util.h" | 22 #include "ui/gfx/transform.h" |
| 23 | 23 |
| 24 #if defined(USE_OZONE) | 24 #if defined(USE_OZONE) |
| 25 #include "ui/ozone/public/cursor_factory_ozone.h" | 25 #include "ui/ozone/public/cursor_factory_ozone.h" |
| 26 #endif | 26 #endif |
| 27 | 27 |
| 28 #if defined(USE_X11) | 28 #if defined(USE_X11) |
| 29 #include "ui/base/cursor/cursor_loader_x11.h" | 29 #include "ui/base/cursor/cursor_loader_x11.h" |
| 30 #endif | 30 #endif |
| 31 | 31 |
| 32 namespace exo { | 32 namespace exo { |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 const float kLargeCursorScale = 2.8f; | 35 // TODO: Some accessibility features, including large cursors, disable hardware |
|
reveman
2017/03/30 07:47:53
nit: TODO(name) and please add a bug number
Dominik Laskowski
2017/04/05 17:59:25
Done. TODO(oshima) to be consistent with:
https:/
| |
| 36 // cursors. Ash does not support compositing for custom cursors, so it replaces | |
| 37 // them with the default cursor. As a result, this scale has no effect for now. | |
| 38 float GetCursorScale(ui::CursorSetType cursor_set) { | |
| 39 return cursor_set == ui::CURSOR_SET_LARGE ? 2.8f : 1.0f; | |
| 40 } | |
| 36 | 41 |
| 37 // Synthesized events typically lack floating point precision so to avoid | 42 // Synthesized events typically lack floating point precision so to avoid |
| 38 // generating mouse event jitter we consider the location of these events | 43 // generating mouse event jitter we consider the location of these events |
| 39 // to be the same as |location| if floored values match. | 44 // to be the same as |location| if floored values match. |
| 40 bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) { | 45 bool SameLocation(const ui::LocatedEvent* event, const gfx::PointF& location) { |
| 41 if (event->flags() & ui::EF_IS_SYNTHESIZED) | 46 if (event->flags() & ui::EF_IS_SYNTHESIZED) |
| 42 return event->location() == gfx::ToFlooredPoint(location); | 47 return event->location() == gfx::ToFlooredPoint(location); |
| 43 | 48 |
| 44 return event->location_f() == location; | 49 return event->location_f() == location; |
| 45 } | 50 } |
| 46 | 51 |
| 47 } // namespace | 52 } // namespace |
| 48 | 53 |
| 49 //////////////////////////////////////////////////////////////////////////////// | 54 //////////////////////////////////////////////////////////////////////////////// |
| 50 // Pointer, public: | 55 // Pointer, public: |
| 51 | 56 |
| 52 Pointer::Pointer(PointerDelegate* delegate) | 57 Pointer::Pointer(PointerDelegate* delegate) |
| 53 : delegate_(delegate), | 58 : delegate_(delegate), |
| 54 cursor_(ui::kCursorNull), | 59 cursor_(new aura::Window(nullptr)), |
| 55 cursor_capture_source_id_(base::UnguessableToken::Create()), | 60 cursor_capture_source_id_(base::UnguessableToken::Create()), |
| 56 cursor_capture_weak_ptr_factory_(this) { | 61 cursor_capture_weak_ptr_factory_(this) { |
| 57 auto* helper = WMHelper::GetInstance(); | 62 auto* helper = WMHelper::GetInstance(); |
| 58 helper->AddPreTargetHandler(this); | 63 helper->AddPreTargetHandler(this); |
| 59 helper->AddCursorObserver(this); | 64 helper->AddCursorObserver(this); |
| 65 | |
| 66 cursor_scale_ = GetCursorScale(helper->GetCursorSet()); | |
| 67 | |
| 68 cursor_->SetName("ExoCursor"); | |
| 69 cursor_->Init(ui::LAYER_NOT_DRAWN); | |
| 70 cursor_->set_owned_by_parent(false); | |
| 71 OnCursorDisplayChanging(display::Screen::GetScreen()->GetPrimaryDisplay()); | |
| 60 } | 72 } |
| 61 | 73 |
| 62 Pointer::~Pointer() { | 74 Pointer::~Pointer() { |
| 63 delegate_->OnPointerDestroying(this); | 75 delegate_->OnPointerDestroying(this); |
| 64 if (surface_) | 76 if (surface_) |
| 65 surface_->RemoveSurfaceObserver(this); | 77 surface_->RemoveSurfaceObserver(this); |
| 66 if (focus_) { | 78 if (focus_) { |
| 67 focus_->RemoveSurfaceObserver(this); | 79 focus_->RemoveSurfaceObserver(this); |
| 68 focus_->UnregisterCursorProvider(this); | 80 focus_->UnregisterCursorProvider(this); |
| 69 } | 81 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 81 bool cursor_changed = false; | 93 bool cursor_changed = false; |
| 82 | 94 |
| 83 // If surface is different than the current pointer surface then remove the | 95 // If surface is different than the current pointer surface then remove the |
| 84 // current surface and add the new surface. | 96 // current surface and add the new surface. |
| 85 if (surface != surface_) { | 97 if (surface != surface_) { |
| 86 if (surface && surface->HasSurfaceDelegate()) { | 98 if (surface && surface->HasSurfaceDelegate()) { |
| 87 DLOG(ERROR) << "Surface has already been assigned a role"; | 99 DLOG(ERROR) << "Surface has already been assigned a role"; |
| 88 return; | 100 return; |
| 89 } | 101 } |
| 90 if (surface_) { | 102 if (surface_) { |
| 91 surface_->window()->SetTransform(gfx::Transform()); | 103 cursor_->RemoveChild(surface_->window()); |
| 92 WMHelper::GetInstance() | |
| 93 ->GetContainer(ash::kShellWindowId_MouseCursorContainer) | |
| 94 ->RemoveChild(surface_->window()); | |
| 95 surface_->SetSurfaceDelegate(nullptr); | 104 surface_->SetSurfaceDelegate(nullptr); |
| 96 surface_->RemoveSurfaceObserver(this); | 105 surface_->RemoveSurfaceObserver(this); |
| 97 } | 106 } |
| 98 surface_ = surface; | 107 surface_ = surface; |
| 99 if (surface_) { | 108 if (surface_) { |
| 100 surface_->SetSurfaceDelegate(this); | 109 surface_->SetSurfaceDelegate(this); |
| 101 surface_->AddSurfaceObserver(this); | 110 surface_->AddSurfaceObserver(this); |
| 102 // Note: Surface window needs to be added to the tree so we can take a | 111 cursor_->AddChild(surface_->window()); |
| 103 // snapshot. Where in the tree is not important but we might as well use | 112 surface_->window()->Show(); |
| 104 // the cursor container. | |
| 105 WMHelper::GetInstance() | |
| 106 ->GetContainer(ash::kShellWindowId_MouseCursorContainer) | |
| 107 ->AddChild(surface_->window()); | |
| 108 } | 113 } |
| 109 cursor_changed = true; | 114 cursor_changed = true; |
| 110 } | 115 } |
| 111 | 116 |
| 112 // Update hotspot. | 117 // Update hotspot. |
| 113 if (hotspot != hotspot_) { | 118 if (hotspot != hotspot_) { |
| 114 hotspot_ = hotspot; | 119 hotspot_ = hotspot; |
| 115 cursor_changed = true; | 120 cursor_changed = true; |
| 116 } | 121 } |
| 117 | 122 |
| 118 // Early out if cursor did not change. | 123 // Early out if cursor did not change. |
| 119 if (!cursor_changed) | 124 if (!cursor_changed) |
| 120 return; | 125 return; |
| 121 | 126 |
| 122 // If |surface_| is set then asynchronously capture a snapshot of cursor, | 127 // If |surface_| is set then asynchronously capture a snapshot of cursor, |
| 123 // otherwise cancel pending capture and immediately set the cursor to "none". | 128 // otherwise cancel pending capture and immediately set the cursor to "none". |
| 124 if (surface_) { | 129 if (surface_) { |
| 125 CaptureCursor(); | 130 CaptureCursor(false); |
| 126 } else { | 131 } else { |
| 127 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | 132 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 128 cursor_ = ui::kCursorNone; | 133 UpdateCursor(ui::kCursorNone, false); |
| 129 UpdateCursor(); | |
| 130 } | 134 } |
| 131 } | 135 } |
| 132 | 136 |
| 133 gfx::NativeCursor Pointer::GetCursor() { | 137 gfx::NativeCursor Pointer::GetCursor() { |
| 134 return cursor_; | 138 if (!focus_) |
|
reveman
2017/03/30 07:47:53
why does all this need to change? I think the prev
Dominik Laskowski
2017/04/05 17:59:25
Keeping track of the latest cursor is unnecessary,
| |
| 139 return ui::kCursorNull; | |
|
reveman
2017/03/30 07:47:53
I think returning null cursor in this case is inco
Dominik Laskowski
2017/04/05 17:59:25
This is equivalent to the old code. Also, the curs
| |
| 140 | |
| 141 aura::client::CursorClient* cursor_client = | |
| 142 aura::client::GetCursorClient(focus_->window()->GetRootWindow()); | |
| 143 return cursor_client ? cursor_client->GetCursor() : ui::kCursorNull; | |
| 135 } | 144 } |
| 136 | 145 |
| 137 //////////////////////////////////////////////////////////////////////////////// | 146 //////////////////////////////////////////////////////////////////////////////// |
| 138 // ui::EventHandler overrides: | 147 // ui::EventHandler overrides: |
| 139 | 148 |
| 140 void Pointer::OnMouseEvent(ui::MouseEvent* event) { | 149 void Pointer::OnMouseEvent(ui::MouseEvent* event) { |
| 141 Surface* target = GetEffectiveTargetForEvent(event); | 150 Surface* target = GetEffectiveTargetForEvent(event); |
| 142 | 151 |
| 143 // If target is different than the current pointer focus then we need to | 152 // If target is different than the current pointer focus then we need to |
| 144 // generate enter and leave events. | 153 // generate enter and leave events. |
| 145 if (target != focus_) { | 154 if (target != focus_) { |
| 146 // First generate a leave event if we currently have a target in focus. | 155 // First generate a leave event if we currently have a target in focus. |
| 147 if (focus_) { | 156 if (focus_) { |
| 148 delegate_->OnPointerLeave(focus_); | 157 delegate_->OnPointerLeave(focus_); |
| 149 focus_->RemoveSurfaceObserver(this); | 158 focus_->RemoveSurfaceObserver(this); |
| 150 // Require SetCursor() to be called and cursor to be re-defined in | 159 // Require SetCursor() to be called and cursor to be re-defined in |
| 151 // response to each OnPointerEnter() call. | 160 // response to each OnPointerEnter() call. |
| 152 focus_->UnregisterCursorProvider(this); | 161 focus_->UnregisterCursorProvider(this); |
| 153 focus_ = nullptr; | 162 focus_ = nullptr; |
| 154 cursor_ = ui::kCursorNull; | |
| 155 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | 163 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 156 } | 164 } |
| 157 // Second generate an enter event if focus moved to a new target. | 165 // Second generate an enter event if focus moved to a new target. |
| 158 if (target) { | 166 if (target) { |
| 159 delegate_->OnPointerEnter(target, event->location_f(), | 167 delegate_->OnPointerEnter(target, event->location_f(), |
| 160 event->button_flags()); | 168 event->button_flags()); |
| 161 location_ = event->location_f(); | 169 location_ = event->location_f(); |
| 162 focus_ = target; | 170 focus_ = target; |
| 163 focus_->AddSurfaceObserver(this); | 171 focus_->AddSurfaceObserver(this); |
| 164 focus_->RegisterCursorProvider(this); | 172 focus_->RegisterCursorProvider(this); |
| 173 | |
| 174 if (surface_) | |
|
reveman
2017/03/30 07:47:53
this is incorrect I think. the client needs to pro
Dominik Laskowski
2017/04/05 17:59:25
The client does not do that currently. Is that req
| |
| 175 CaptureCursor(false); | |
| 165 } | 176 } |
| 166 delegate_->OnPointerFrame(); | 177 delegate_->OnPointerFrame(); |
| 167 } | 178 } |
| 168 | 179 |
| 169 if (!focus_) | 180 if (!focus_) |
| 170 return; | 181 return; |
| 171 | 182 |
| 172 if (event->IsMouseEvent() && event->type() != ui::ET_MOUSE_EXITED) { | 183 if (event->IsMouseEvent() && event->type() != ui::ET_MOUSE_EXITED) { |
| 173 // Generate motion event if location changed. We need to check location | 184 // Generate motion event if location changed. We need to check location |
| 174 // here as mouse movement can generate both "moved" and "entered" events | 185 // here as mouse movement can generate both "moved" and "entered" events |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 case ui::ET_MOUSE_MOVED: | 230 case ui::ET_MOUSE_MOVED: |
| 220 case ui::ET_MOUSE_DRAGGED: | 231 case ui::ET_MOUSE_DRAGGED: |
| 221 case ui::ET_MOUSE_ENTERED: | 232 case ui::ET_MOUSE_ENTERED: |
| 222 case ui::ET_MOUSE_EXITED: | 233 case ui::ET_MOUSE_EXITED: |
| 223 case ui::ET_MOUSE_CAPTURE_CHANGED: | 234 case ui::ET_MOUSE_CAPTURE_CHANGED: |
| 224 break; | 235 break; |
| 225 default: | 236 default: |
| 226 NOTREACHED(); | 237 NOTREACHED(); |
| 227 break; | 238 break; |
| 228 } | 239 } |
| 229 | |
| 230 UpdateCursorScale(); | |
| 231 } | 240 } |
| 232 | 241 |
| 233 void Pointer::OnScrollEvent(ui::ScrollEvent* event) { | 242 void Pointer::OnScrollEvent(ui::ScrollEvent* event) { |
| 234 OnMouseEvent(event); | 243 OnMouseEvent(event); |
| 235 } | 244 } |
| 236 | 245 |
| 237 //////////////////////////////////////////////////////////////////////////////// | 246 //////////////////////////////////////////////////////////////////////////////// |
| 238 // WMHelper::CursorObserver overrides: | 247 // WMHelper::CursorObserver overrides: |
| 239 | 248 |
| 240 void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { | 249 void Pointer::OnCursorSetChanged(ui::CursorSetType cursor_set) { |
| 241 if (focus_) | 250 cursor_scale_ = GetCursorScale(cursor_set); |
| 242 UpdateCursorScale(); | 251 if (focus_ && surface_) |
| 252 CaptureCursor(false); | |
| 253 } | |
| 254 | |
| 255 void Pointer::OnCursorDisplayChanging(const display::Display& display) { | |
| 256 WMHelper* helper = WMHelper::GetInstance(); | |
| 257 aura::Window* container = helper->GetContainer( | |
| 258 display.id(), ash::kShellWindowId_MouseCursorContainer); | |
| 259 | |
| 260 // Reparent the cursor to the root window where the mouse is located. | |
| 261 if (container->GetRootWindow() != cursor_->GetRootWindow()) { | |
| 262 if (cursor_->parent()) | |
| 263 cursor_->parent()->RemoveChild(cursor_.get()); | |
| 264 container->AddChild(cursor_.get()); | |
| 265 } | |
| 266 | |
| 267 auto info = helper->GetDisplayInfo(display.id()); | |
| 268 display_scale_ = info.GetEffectiveUIScale() * info.device_scale_factor(); | |
| 269 device_scale_factor_ = display.device_scale_factor(); | |
| 270 | |
| 271 if (focus_ && surface_) { | |
| 272 // Capture is asynchronous, so avoid rendering old cursor in the meantime. | |
|
reveman
2017/03/30 07:47:53
I don't understand why we need to do all this. Thi
Dominik Laskowski
2017/04/05 17:59:25
This special case is needed when dragging across d
| |
| 273 cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 274 UpdateCursor(ui::kCursorNone, true); | |
| 275 // Force the cursor to be updated even if locked. | |
| 276 CaptureCursor(true); | |
| 277 } | |
| 243 } | 278 } |
| 244 | 279 |
| 245 //////////////////////////////////////////////////////////////////////////////// | 280 //////////////////////////////////////////////////////////////////////////////// |
| 246 // SurfaceDelegate overrides: | 281 // SurfaceDelegate overrides: |
| 247 | 282 |
| 248 void Pointer::OnSurfaceCommit() { | 283 void Pointer::OnSurfaceCommit() { |
| 249 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); | 284 surface_->CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces(); |
| 250 surface_->CommitSurfaceHierarchy(); | 285 surface_->CommitSurfaceHierarchy(); |
| 251 | 286 |
| 252 // Capture new cursor to reflect result of commit. | 287 // Capture new cursor to reflect result of commit. |
| 253 if (focus_) | 288 if (focus_) |
| 254 CaptureCursor(); | 289 CaptureCursor(false); |
| 255 } | 290 } |
| 256 | 291 |
| 257 bool Pointer::IsSurfaceSynchronized() const { | 292 bool Pointer::IsSurfaceSynchronized() const { |
| 258 // A pointer surface is always desynchronized. | 293 // A pointer surface is always desynchronized. |
| 259 return false; | 294 return false; |
| 260 } | 295 } |
| 261 | 296 |
| 262 //////////////////////////////////////////////////////////////////////////////// | 297 //////////////////////////////////////////////////////////////////////////////// |
| 263 // SurfaceObserver overrides: | 298 // SurfaceObserver overrides: |
| 264 | 299 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 276 | 311 |
| 277 Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { | 312 Surface* Pointer::GetEffectiveTargetForEvent(ui::Event* event) const { |
| 278 Surface* target = | 313 Surface* target = |
| 279 Surface::AsSurface(static_cast<aura::Window*>(event->target())); | 314 Surface::AsSurface(static_cast<aura::Window*>(event->target())); |
| 280 if (!target) | 315 if (!target) |
| 281 return nullptr; | 316 return nullptr; |
| 282 | 317 |
| 283 return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; | 318 return delegate_->CanAcceptPointerEventsForSurface(target) ? target : nullptr; |
| 284 } | 319 } |
| 285 | 320 |
| 286 void Pointer::UpdateCursorScale() { | 321 void Pointer::CaptureCursor(bool force) { |
| 287 DCHECK(focus_); | |
| 288 | |
| 289 display::Screen* screen = display::Screen::GetScreen(); | |
| 290 WMHelper* helper = WMHelper::GetInstance(); | |
| 291 | |
| 292 // Update cursor scale if the effective UI scale has changed. | |
| 293 display::Display display = screen->GetDisplayNearestWindow(focus_->window()); | |
| 294 float scale = helper->GetDisplayInfo(display.id()).GetEffectiveUIScale(); | |
| 295 | |
| 296 if (display::Display::HasInternalDisplay()) { | |
| 297 float primary_device_scale_factor = | |
| 298 screen->GetPrimaryDisplay().device_scale_factor(); | |
| 299 // The size of the cursor surface is the quotient of its physical size and | |
| 300 // the DSF of the primary display. The physical size is proportional to the | |
| 301 // DSF of the internal display. For external displays (and the internal | |
| 302 // display when secondary to a display with a different DSF), scale the | |
| 303 // cursor so its physical size matches with the single display case. | |
| 304 if (!display.IsInternal() || | |
| 305 display.device_scale_factor() != primary_device_scale_factor) { | |
| 306 scale *= primary_device_scale_factor / | |
| 307 helper->GetDisplayInfo(display::Display::InternalDisplayId()) | |
| 308 .device_scale_factor(); | |
| 309 } | |
| 310 } | |
| 311 | |
| 312 if (helper->GetCursorSet() == ui::CURSOR_SET_LARGE) | |
| 313 scale *= kLargeCursorScale; | |
| 314 | |
| 315 if (scale != cursor_scale_) { | |
| 316 cursor_scale_ = scale; | |
| 317 if (surface_) | |
| 318 CaptureCursor(); | |
| 319 } | |
| 320 } | |
| 321 | |
| 322 void Pointer::CaptureCursor() { | |
| 323 DCHECK(surface_); | 322 DCHECK(surface_); |
| 324 DCHECK(focus_); | 323 DCHECK(focus_); |
| 325 | 324 |
| 326 // Set UI scale before submitting capture request. | 325 float scale = cursor_scale_ * display_scale_; |
| 327 surface_->window()->layer()->SetTransform( | 326 float layer_scale = scale / device_scale_factor_; |
| 328 gfx::GetScaleTransform(gfx::Point(), cursor_scale_)); | |
| 329 | 327 |
| 330 float primary_device_scale_factor = | 328 gfx::Transform transform; |
| 331 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); | 329 transform.Scale(layer_scale, layer_scale); |
| 330 surface_->window()->SetTransform(transform); | |
| 332 | 331 |
| 333 std::unique_ptr<cc::CopyOutputRequest> request = | 332 std::unique_ptr<cc::CopyOutputRequest> request = |
| 334 cc::CopyOutputRequest::CreateBitmapRequest( | 333 cc::CopyOutputRequest::CreateBitmapRequest( |
| 335 base::Bind(&Pointer::OnCursorCaptured, | 334 base::Bind(&Pointer::OnCursorCaptured, |
| 336 cursor_capture_weak_ptr_factory_.GetWeakPtr(), | 335 cursor_capture_weak_ptr_factory_.GetWeakPtr(), |
| 337 gfx::ScaleToFlooredPoint( | 336 gfx::ScaleToFlooredPoint(hotspot_, scale), force)); |
| 338 hotspot_, | 337 |
| 339 // |hotspot_| is in surface coordinate space so apply | |
| 340 // both device scale and UI scale. | |
| 341 cursor_scale_ * primary_device_scale_factor))); | |
| 342 request->set_source(cursor_capture_source_id_); | 338 request->set_source(cursor_capture_source_id_); |
| 343 surface_->window()->layer()->RequestCopyOfOutput(std::move(request)); | 339 cursor_->layer()->RequestCopyOfOutput(std::move(request)); |
| 340 | |
| 341 // Prevent subsequent requests in the same frame from aborting this capture. | |
|
reveman
2017/03/30 07:47:53
why is this needed?
Dominik Laskowski
2017/04/05 17:59:25
If the client happens to commit or call wl_pointer
| |
| 342 if (force) | |
| 343 cursor_capture_source_id_ = base::UnguessableToken::Create(); | |
| 344 } | 344 } |
| 345 | 345 |
| 346 void Pointer::OnCursorCaptured(const gfx::Point& hotspot, | 346 void Pointer::OnCursorCaptured(gfx::Point hotspot, |
| 347 bool force, | |
| 347 std::unique_ptr<cc::CopyOutputResult> result) { | 348 std::unique_ptr<cc::CopyOutputResult> result) { |
| 348 if (!focus_) | 349 if (!focus_) |
| 349 return; | 350 return; |
| 350 | 351 |
| 351 cursor_ = ui::kCursorNone; | 352 gfx::NativeCursor cursor = ui::kCursorNull; |
| 352 if (!result->IsEmpty()) { | 353 if (!result->IsEmpty()) { |
| 353 DCHECK(result->HasBitmap()); | 354 DCHECK(result->HasBitmap()); |
| 354 std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); | 355 std::unique_ptr<SkBitmap> bitmap = result->TakeBitmap(); |
| 355 | 356 |
| 356 ui::PlatformCursor platform_cursor; | 357 ui::PlatformCursor platform_cursor; |
| 357 #if defined(USE_OZONE) | 358 #if defined(USE_OZONE) |
| 358 // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers | 359 // TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers |
| 359 // and use that here instead of the current bitmap API. crbug.com/686600 | 360 // and use that here instead of the current bitmap API. crbug.com/686600 |
| 360 platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( | 361 platform_cursor = ui::CursorFactoryOzone::GetInstance()->CreateImageCursor( |
| 361 *bitmap.get(), hotspot); | 362 *bitmap.get(), hotspot); |
| 362 #elif defined(USE_X11) | 363 #elif defined(USE_X11) |
| 363 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); | 364 XcursorImage* image = ui::SkBitmapToXcursorImage(bitmap.get(), hotspot); |
| 364 platform_cursor = ui::CreateReffedCustomXCursor(image); | 365 platform_cursor = ui::CreateReffedCustomXCursor(image); |
| 365 #endif | 366 #endif |
| 366 cursor_ = ui::kCursorCustom; | 367 cursor = ui::kCursorCustom; |
| 367 cursor_.SetPlatformCursor(platform_cursor); | 368 cursor.SetPlatformCursor(platform_cursor); |
| 368 #if defined(USE_OZONE) | 369 #if defined(USE_OZONE) |
| 369 ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor); | 370 ui::CursorFactoryOzone::GetInstance()->UnrefImageCursor(platform_cursor); |
| 370 #elif defined(USE_X11) | 371 #elif defined(USE_X11) |
| 371 ui::UnrefCustomXCursor(platform_cursor); | 372 ui::UnrefCustomXCursor(platform_cursor); |
| 372 #endif | 373 #endif |
| 373 } | 374 } |
| 374 | 375 |
| 375 UpdateCursor(); | 376 UpdateCursor(cursor, force); |
| 376 } | 377 } |
| 377 | 378 |
| 378 void Pointer::UpdateCursor() { | 379 void Pointer::UpdateCursor(gfx::NativeCursor cursor, bool force) { |
| 379 DCHECK(focus_); | 380 DCHECK(focus_); |
| 380 | 381 |
| 381 aura::client::CursorClient* cursor_client = | 382 aura::client::CursorClient* cursor_client = |
| 382 aura::client::GetCursorClient(focus_->window()->GetRootWindow()); | 383 aura::client::GetCursorClient(focus_->window()->GetRootWindow()); |
| 383 if (cursor_client) | 384 if (!cursor_client) |
| 384 cursor_client->SetCursor(cursor_); | 385 return; |
| 386 | |
| 387 cursor_client->SetCursor(cursor); | |
| 388 | |
| 389 if (force && cursor_client->IsCursorLocked()) | |
|
reveman
2017/03/30 07:47:53
what's the situation where this is currently causi
Dominik Laskowski
2017/04/05 17:59:25
|force| being true implies that the cursor is lock
| |
| 390 WMHelper::GetInstance()->SetCursor(cursor); | |
| 385 } | 391 } |
| 386 | 392 |
| 387 } // namespace exo | 393 } // namespace exo |
| OLD | NEW |