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

Unified Diff: components/exo/shell_surface.cc

Issue 2361993003: Draw underlay behind android apps using talkback (Closed)
Patch Set: Properly show shadow on app launch Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: components/exo/shell_surface.cc
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 6248a27c13212c96588327d4db216d9844e79d12..1770e0c1cd2f1a7ea6b9be8a722df8f5854aa52f 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -5,10 +5,13 @@
#include "components/exo/shell_surface.h"
#include "ash/aura/wm_window_aura.h"
+#include "ash/common/accessibility_delegate.h"
#include "ash/common/shell_window_ids.h"
+#include "ash/common/system/tray/system_tray_notifier.h"
#include "ash/common/wm/window_resizer.h"
#include "ash/common/wm/window_state.h"
#include "ash/common/wm/window_state_delegate.h"
+#include "ash/common/wm_shell.h"
#include "ash/shell.h"
#include "ash/wm/window_state_aura.h"
#include "ash/wm/window_util.h"
@@ -36,6 +39,10 @@
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_util.h"
+#if defined(OS_CHROMEOS)
+#include "chromeos/audio/chromeos_sounds.h"
+#endif
+
DECLARE_WINDOW_PROPERTY_TYPE(std::string*)
namespace exo {
@@ -86,7 +93,7 @@ class CustomFrameView : public views::NonClientFrameView {
class CustomWindowTargeter : public aura::WindowTargeter {
reveman 2016/09/28 16:11:50 Does this really need to know about the shadow und
erosky 2016/09/28 19:21:12 This still needs to know about the shadow_underlay
public:
- CustomWindowTargeter() {}
+ CustomWindowTargeter() : shadow_underlay_(nullptr) {}
~CustomWindowTargeter() override {}
// Overridden from aura::WindowTargeter:
@@ -97,15 +104,40 @@ class CustomWindowTargeter : public aura::WindowTargeter {
return false;
gfx::Point local_point = event.location();
- if (window->parent())
- aura::Window::ConvertPointToTarget(window->parent(), window,
+
+ if (shadow_underlay_ && !shadow_underlay_->ignore_events()) {
+ aura::Window::ConvertPointToTarget(window->parent(), shadow_underlay_,
&local_point);
+ return gfx::Rect(shadow_underlay_->layer()->size()).Contains(local_point);
+ }
+
+ aura::Window::ConvertPointToTarget(window->parent(), window, &local_point);
aura::Window::ConvertPointToTarget(window, surface->window(), &local_point);
return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1)));
}
+ ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
+ ui::Event* event) override {
+ aura::Window* window = static_cast<aura::Window*>(root);
+ Surface* surface = ShellSurface::GetMainSurface(window);
+ if (surface && event->IsLocatedEvent() && shadow_underlay_ &&
+ !shadow_underlay_->ignore_events()) {
+ gfx::Point local_point = event->AsLocatedEvent()->location();
+ aura::Window::ConvertPointToTarget(window, surface->window(),
+ &local_point);
+ if (!surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))))
+ return shadow_underlay_;
+ }
+ return aura::WindowTargeter::FindTargetForEvent(root, event);
+ }
+
+ void set_shadow_underlay(aura::Window* shadow_underlay) {
+ shadow_underlay_ = shadow_underlay;
+ }
+
private:
+ aura::Window* shadow_underlay_;
reveman 2016/09/28 16:11:51 nit: blank line before DISALLOW_..
erosky 2016/09/28 19:21:12 Done.
DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter);
};
@@ -301,6 +333,11 @@ ShellSurface::~ShellSurface() {
surface_->SetSurfaceDelegate(nullptr);
surface_->RemoveSurfaceObserver(this);
}
+ if (ash::WmShell::HasInstance() &&
+ ash::WmShell::Get()->system_tray_notifier()) {
reveman 2016/09/28 16:11:50 Do we have to check ash::WmShell::HasInstance() &&
erosky 2016/09/28 19:21:13 Done.
+ ash::WmShell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(
+ this);
+ }
}
void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
@@ -725,6 +762,16 @@ gfx::Size ShellSurface::GetPreferredSize() const {
}
////////////////////////////////////////////////////////////////////////////////
+// ash::AccessibilityObserver overrides:
+
+void ShellSurface::OnAccessibilityModeChanged(
+ ash::AccessibilityNotificationVisibility) {
+ audio_feedback_ =
+ ash::WmShell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
+ UpdateShadow();
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ash::wm::WindowStateObserver overrides:
void ShellSurface::OnPreWindowStateTypeChange(
@@ -820,12 +867,36 @@ void ShellSurface::OnWindowActivated(
lost_active == widget_->GetNativeWindow()) {
DCHECK(activatable_);
Configure();
+ UpdateShadow();
}
}
////////////////////////////////////////////////////////////////////////////////
// ui::EventHandler overrides:
+void ShellSurface::OnEvent(ui::Event* event) {
+ if (event->IsLocatedEvent() && event->target() == shadow_underlay_ &&
reveman 2016/09/28 16:11:50 Same here. Can this use "event->target() == widget
erosky 2016/09/28 19:21:12 widget_->GetNativeWindow() represents the actual a
+ shadow_underlay_ && !shadow_underlay_->ignore_events()) {
+#if defined(OS_CHROMEOS)
+ ui::EventType sound_types[] = {
reveman 2016/09/28 16:11:51 nit: s/ui::EventType sound_types/const ui::EventTy
erosky 2016/09/28 19:21:13 Done.
+ ui::ET_TOUCH_PRESSED, ui::ET_POINTER_DOWN,
+ ui::ET_POINTER_WHEEL_CHANGED, ui::ET_SCROLL,
+ ui::ET_SCROLL_FLING_START, ui::ET_GESTURE_BEGIN,
+ ui::ET_MOUSE_PRESSED, ui::ET_MOUSEWHEEL};
+ for (ui::EventType e : sound_types) {
reveman 2016/09/28 16:11:50 nit: I think this would be a good place to use std
erosky 2016/09/28 19:21:13 Done.
+ if (event->type() == e) {
+ ash::WmShell::Get()->accessibility_delegate()->PlayEarcon(
+ chromeos::SOUND_VOLUME_ADJUST);
+ break;
+ }
+ }
+#endif
+ event->SetHandled();
+ return;
+ }
+ views::View::OnEvent(event);
+}
+
void ShellSurface::OnKeyEvent(ui::KeyEvent* event) {
if (!resizer_) {
views::View::OnKeyEvent(event);
@@ -981,6 +1052,11 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) {
window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>(
new CustomWindowStateDelegate(widget_)));
+ // Receive accessibility changes to update shadow underlay.
+ ash::WmShell::Get()->system_tray_notifier()->AddAccessibilityObserver(this);
+ audio_feedback_ =
+ ash::WmShell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
+
// Show widget next time Commit() is called.
pending_show_widget_ = true;
}
@@ -1240,8 +1316,8 @@ void ShellSurface::UpdateShadow() {
// Always create and show the underlay, even in maximized/fullscreen.
if (!shadow_underlay_) {
shadow_underlay_ = new aura::Window(nullptr);
+ shadow_underlay_->SetTargetHandler(this);
DCHECK(shadow_underlay_->owned_by_parent());
- shadow_underlay_->set_ignore_events(true);
// Ensure the background area inside the shadow is solid black.
// Clients that provide translucent contents should not be using
// rectangular shadows as this method requires opaque contents to
@@ -1251,18 +1327,25 @@ void ShellSurface::UpdateShadow() {
DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely());
window->AddChild(shadow_underlay_);
window->StackChildAtBottom(shadow_underlay_);
+ static_cast<CustomWindowTargeter*>(
+ static_cast<ui::EventTarget*>(window)->GetEventTargeter())
+ ->set_shadow_underlay(shadow_underlay_);
}
+ bool underlay_capture_events = audio_feedback_ && widget_->IsActive();
+ shadow_underlay_->set_ignore_events(!underlay_capture_events);
+
float shadow_underlay_opacity = rectangular_shadow_background_opacity_;
// Put the black background layer behind the window if
- // 1) the window is in immersive fullscreen.
+ // 1) the window is in immersive fullscreen or spoken_feedback/talkback
reveman 2016/09/28 16:11:50 nit: s/spoken_feedback/spoken feedback/ and remove
erosky 2016/09/28 19:21:13 Done.
+ // is enabled.
// 2) the window can control the bounds of the window in fullscreen (
// thus the background can be visible).
// 3) the window has no transform (the transformed background may
// not cover the entire background, e.g. overview mode).
- if (widget_->IsFullscreen() &&
+ if ((widget_->IsFullscreen() || underlay_capture_events) &&
reveman 2016/09/28 16:11:50 use helper function?
erosky 2016/09/28 19:21:13 This is the only place where the check happens, so
ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() &&
- window->layer()->transform().IsIdentity()) {
+ window->layer()->GetTargetTransform().IsIdentity()) {
reveman 2016/09/28 16:11:50 is this needed as part of this patch?
erosky 2016/09/28 19:21:13 Yeah, otherwise the shadow won't initially show-up
gfx::Point origin;
origin -= window->bounds().origin().OffsetFromOrigin();
shadow_bounds.set_origin(origin);

Powered by Google App Engine
This is Rietveld 408576698