Commit 18a62fe6 authored by David Bienvenu's avatar David Bienvenu Committed by Commit Bot

Mark windows occluded when screen is locked, on Windows.

When native-win-occlusion is turned on, this will cause the page visiblity API to get triggered
when the screen is locked/unlocked.

Bug: 532128, 813093
Change-Id: Ic747188d31ebf9a692a6913d9b84a70f86c9d2aa
Reviewed-on: https://chromium-review.googlesource.com/c/1481581Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635202}
parent 1ce2fdbe
......@@ -221,6 +221,10 @@ jumbo_component("aura") {
]
}
if (is_win) {
libs = [ "wtsapi32.lib" ]
}
if (use_ozone) {
deps += [ "//ui/ozone" ]
public += [ "screen_ozone.h" ]
......
......@@ -99,7 +99,10 @@ NativeWindowOcclusionTrackerWin::NativeWindowOcclusionTrackerWin()
base::TaskPriority::USER_VISIBLE,
// Occlusion calculation doesn't need to happen on shutdown.
// event hooks should also be cleaned up by Windows.
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
session_change_observer_(
base::BindRepeating(&NativeWindowOcclusionTrackerWin::OnSessionChange,
base::Unretained(this))) {
occlusion_calculator_ = std::make_unique<WindowOcclusionCalculator>(
update_occlusion_task_runner_, base::SequencedTaskRunnerHandle::Get());
}
......@@ -186,6 +189,19 @@ void NativeWindowOcclusionTrackerWin::UpdateOcclusionState(
}
}
void NativeWindowOcclusionTrackerWin::OnSessionChange(WPARAM status_code) {
if (status_code == WTS_SESSION_LOCK) {
// Tell all root windows that they're occluded.
for (const auto& root_window_hwnd_pair : hwnd_root_window_map_) {
root_window_hwnd_pair.second->GetHost()->SetNativeWindowOcclusionState(
Window::OcclusionState::OCCLUDED);
}
}
// Other session changes don't need to trigger occlusion calculation. In
// particular, UNLOCK will cause a foreground window change, which will
// trigger an occlusion calculation on its own.
}
NativeWindowOcclusionTrackerWin::WindowOcclusionCalculator::
WindowOcclusionCalculator(
scoped_refptr<base::SequencedTaskRunner> task_runner,
......
......@@ -8,6 +8,7 @@
#include <windows.h>
#include <winuser.h>
#include <memory>
#include <vector>
#include "base/containers/flat_map.h"
......@@ -18,6 +19,7 @@
#include "ui/aura/aura_export.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/base/win/session_change_observer.h"
namespace aura {
......@@ -199,6 +201,10 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin : public WindowObserver {
void UpdateOcclusionState(const base::flat_map<HWND, Window::OcclusionState>&
root_window_hwnds_occlusion_state);
// This is called with session changed notifications. If the screen is locked,
// it marks app windows as occluded.
void OnSessionChange(WPARAM status_code);
// Task runner to call ComputeNativeWindowOcclusionStatus, and to handle
// Windows event notifications, off of the UI thread.
const scoped_refptr<base::SequencedTaskRunner> update_occlusion_task_runner_;
......@@ -213,6 +219,9 @@ class AURA_EXPORT NativeWindowOcclusionTrackerWin : public WindowObserver {
std::unique_ptr<WindowOcclusionCalculator> occlusion_calculator_;
// Manages observation of Windows Session Change messages.
ui::SessionChangeObserver session_change_observer_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowOcclusionTrackerWin);
};
......
......@@ -282,6 +282,8 @@ jumbo_component("base") {
"win/mouse_wheel_util.h",
"win/scoped_ole_initializer.cc",
"win/scoped_ole_initializer.h",
"win/session_change_observer.cc",
"win/session_change_observer.h",
"win/shell.cc",
"win/shell.h",
"win/touch_input.cc",
......@@ -535,6 +537,7 @@ jumbo_component("base") {
"d2d1.lib",
"dwmapi.lib",
"oleacc.lib",
"wtsapi32.lib",
]
} else {
if (!use_aura) {
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/win/windows_session_change_observer.h"
#include "ui/base/win/session_change_observer.h"
#include <wtsapi32.h>
......@@ -18,30 +18,37 @@
#include "base/task/post_task.h"
#include "ui/gfx/win/singleton_hwnd.h"
#include "ui/gfx/win/singleton_hwnd_observer.h"
#include "ui/views/views_delegate.h"
namespace views {
namespace ui {
class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
class SessionChangeObserver::WtsRegistrationNotificationManager {
public:
static WtsRegistrationNotificationManager* GetInstance() {
return base::Singleton<WtsRegistrationNotificationManager>::get();
}
WtsRegistrationNotificationManager() {
AddSingletonHwndObserver();
}
DCHECK(!singleton_hwnd_observer_);
singleton_hwnd_observer_.reset(new gfx::SingletonHwndObserver(
base::BindRepeating(&WtsRegistrationNotificationManager::OnWndProc,
base::Unretained(this))));
~WtsRegistrationNotificationManager() {
RemoveSingletonHwndObserver();
base::OnceClosure wts_register = base::BindOnce(
base::IgnoreResult(&WTSRegisterSessionNotification),
gfx::SingletonHwnd::GetInstance()->hwnd(), NOTIFY_FOR_THIS_SESSION);
base::CreateCOMSTATaskRunnerWithTraits({})->PostTask(
FROM_HERE, std::move(wts_register));
}
void AddObserver(WindowsSessionChangeObserver* observer) {
~WtsRegistrationNotificationManager() { RemoveSingletonHwndObserver(); }
void AddObserver(SessionChangeObserver* observer) {
DCHECK(singleton_hwnd_observer_);
observer_list_.AddObserver(observer);
}
void RemoveObserver(WindowsSessionChangeObserver* observer) {
void RemoveObserver(SessionChangeObserver* observer) {
observer_list_.RemoveObserver(observer);
}
......@@ -52,7 +59,7 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
switch (message) {
case WM_WTSSESSION_CHANGE:
for (WindowsSessionChangeObserver& observer : observer_list_)
for (SessionChangeObserver& observer : observer_list_)
observer.OnSessionChange(wparam);
break;
case WM_DESTROY:
......@@ -61,27 +68,6 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
}
}
void AddSingletonHwndObserver() {
DCHECK(!singleton_hwnd_observer_);
singleton_hwnd_observer_.reset(new gfx::SingletonHwndObserver(
base::Bind(&WtsRegistrationNotificationManager::OnWndProc,
base::Unretained(this))));
base::OnceClosure wts_register = base::BindOnce(
base::IgnoreResult(&WTSRegisterSessionNotification),
gfx::SingletonHwnd::GetInstance()->hwnd(), NOTIFY_FOR_THIS_SESSION);
// This should probably always be async but it wasn't async in the absence
// of a ViewsDelegate prior to the migration to TaskScheduler and making it
// async breaks many unrelated views unittests.
if (ViewsDelegate::GetInstance()) {
base::CreateCOMSTATaskRunnerWithTraits({})->PostTask(
FROM_HERE, std::move(wts_register));
} else {
std::move(wts_register).Run();
}
}
void RemoveSingletonHwndObserver() {
if (!singleton_hwnd_observer_)
return;
......@@ -94,37 +80,35 @@ class WindowsSessionChangeObserver::WtsRegistrationNotificationManager {
// Under both cases we are in shutdown, which means no other worker threads
// can be running.
WTSUnRegisterSessionNotification(gfx::SingletonHwnd::GetInstance()->hwnd());
for (WindowsSessionChangeObserver& observer : observer_list_)
for (SessionChangeObserver& observer : observer_list_)
observer.ClearCallback();
}
base::ObserverList<WindowsSessionChangeObserver, true>::Unchecked
observer_list_;
base::ObserverList<SessionChangeObserver, true>::Unchecked observer_list_;
std::unique_ptr<gfx::SingletonHwndObserver> singleton_hwnd_observer_;
DISALLOW_COPY_AND_ASSIGN(WtsRegistrationNotificationManager);
};
WindowsSessionChangeObserver::WindowsSessionChangeObserver(
const WtsCallback& callback)
SessionChangeObserver::SessionChangeObserver(const WtsCallback& callback)
: callback_(callback) {
DCHECK(!callback_.is_null());
WtsRegistrationNotificationManager::GetInstance()->AddObserver(this);
}
WindowsSessionChangeObserver::~WindowsSessionChangeObserver() {
SessionChangeObserver::~SessionChangeObserver() {
ClearCallback();
}
void WindowsSessionChangeObserver::OnSessionChange(WPARAM wparam) {
void SessionChangeObserver::OnSessionChange(WPARAM wparam) {
callback_.Run(wparam);
}
void WindowsSessionChangeObserver::ClearCallback() {
void SessionChangeObserver::ClearCallback() {
if (!callback_.is_null()) {
callback_.Reset();
WtsRegistrationNotificationManager::GetInstance()->RemoveObserver(this);
}
}
} // namespace views
} // namespace ui
......@@ -2,23 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_WIN_WINDOWS_SESSION_CHANGE_OBSERVER_H_
#define UI_VIEWS_WIN_WINDOWS_SESSION_CHANGE_OBSERVER_H_
#ifndef UI_BASE_WIN_SESSION_CHANGE_OBSERVER_H_
#define UI_BASE_WIN_SESSION_CHANGE_OBSERVER_H_
#include <windows.h>
#include "base/callback.h"
#include "base/macros.h"
#include "ui/base/ui_base_export.h"
namespace views {
namespace ui {
// Calls the provided callback on WM_WTSSESSION_CHANGE messages along with
// managing the tricky business of observing a singleton object.
class WindowsSessionChangeObserver {
class UI_BASE_EXPORT SessionChangeObserver {
public:
typedef base::Callback<void(WPARAM)> WtsCallback;
explicit WindowsSessionChangeObserver(const WtsCallback& callback);
~WindowsSessionChangeObserver();
// WPARAM is the wparam passed to the OnWndProc when message is
// WM_WTSSESSION_CHANGE.
typedef base::RepeatingCallback<void(WPARAM)> WtsCallback;
explicit SessionChangeObserver(const WtsCallback& callback);
~SessionChangeObserver();
private:
class WtsRegistrationNotificationManager;
......@@ -28,9 +31,9 @@ class WindowsSessionChangeObserver {
WtsCallback callback_;
DISALLOW_COPY_AND_ASSIGN(WindowsSessionChangeObserver);
DISALLOW_COPY_AND_ASSIGN(SessionChangeObserver);
};
} // namespace views
} // namespace ui
#endif // UI_VIEWS_WIN_WINDOWS_SESSION_CHANGE_OBSERVER_H_
#endif // UI_BASE_WIN_SESSION_CHANGE_OBSERVER_H_
......@@ -566,7 +566,6 @@ jumbo_component("views") {
"win/hwnd_util.h",
"win/pen_event_processor.h",
"win/scoped_fullscreen_visibility.h",
"win/windows_session_change_observer.h",
]
sources += [
"widget/widget_hwnd_utils.cc",
......@@ -575,14 +574,12 @@ jumbo_component("views") {
"win/hwnd_util_aurawin.cc",
"win/pen_event_processor.cc",
"win/scoped_fullscreen_visibility.cc",
"win/windows_session_change_observer.cc",
]
libs = [
"dwmapi.lib",
"imm32.lib",
"oleacc.lib",
"uiautomationcore.lib",
"wtsapi32.lib",
]
ldflags = [ "/DELAYLOAD:user32.dll" ]
deps += [
......
......@@ -38,6 +38,7 @@
#include "ui/base/win/internal_constants.h"
#include "ui/base/win/lock_state.h"
#include "ui/base/win/mouse_wheel_util.h"
#include "ui/base/win/session_change_observer.h"
#include "ui/base/win/shell.h"
#include "ui/base/win/touch_input.h"
#include "ui/display/win/dpi.h"
......@@ -59,7 +60,6 @@
#include "ui/views/win/fullscreen_handler.h"
#include "ui/views/win/hwnd_message_handler_delegate.h"
#include "ui/views/win/scoped_fullscreen_visibility.h"
#include "ui/views/win/windows_session_change_observer.h"
namespace views {
namespace {
......@@ -1596,9 +1596,9 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
delegate_->HandleCreate();
windows_session_change_observer_.reset(new WindowsSessionChangeObserver(
base::Bind(&HWNDMessageHandler::OnSessionChange,
base::Unretained(this))));
session_change_observer_ =
std::make_unique<ui::SessionChangeObserver>(base::BindRepeating(
&HWNDMessageHandler::OnSessionChange, base::Unretained(this)));
dpi_ = display::win::ScreenWin::GetDPIForHWND(hwnd());
......@@ -1608,7 +1608,7 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
void HWNDMessageHandler::OnDestroy() {
::RemoveProp(hwnd(), ui::kWindowTranslucent);
windows_session_change_observer_.reset(nullptr);
session_change_observer_.reset(nullptr);
delegate_->HandleDestroying();
// If the window going away is a fullscreen window then remove its references
// from the full screen window map.
......
......@@ -44,13 +44,13 @@ class AXSystemCaretWin;
class InputMethod;
class TextInputClient;
class ViewProp;
class SessionChangeObserver;
} // namespace ui
namespace views {
class FullscreenHandler;
class HWNDMessageHandlerDelegate;
class WindowsSessionChangeObserver;
// These two messages aren't defined in winuser.h, but they are sent to windows
// with captions. They appear to paint the window caption and frame.
......@@ -708,8 +708,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
uint32_t current_window_size_message_ = 0;
// Manages observation of Windows Session Change messages.
std::unique_ptr<WindowsSessionChangeObserver>
windows_session_change_observer_;
std::unique_ptr<ui::SessionChangeObserver> session_change_observer_;
// Some assistive software need to track the location of the caret.
std::unique_ptr<ui::AXSystemCaretWin> ax_system_caret_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment