Skip to content

Commit

Permalink
Page Visibility API: visibilitychange on Windows screen lock/unlock
Browse files Browse the repository at this point in the history
BUG=XWALK-5503

Some OSs (e.g. Windows and Linux) don't mark windows as hiden on screen
lock or when other opaque windows fully cover them.
Note that e.g. OSX and Android do this while Windows and Linux don't.
OnSoftVisibilityChanged enables that OS window state is kept as is (on
Linux and Windows) and that e.g. power saving PageVisibility API is still
properly triggered.

The first patch here targets Windows and screen lock.

branch pagevis
  • Loading branch information
astojilj authored and Raphael Kubo da Costa committed Oct 11, 2016
1 parent af25511 commit 8754d66
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 1 deletion.
16 changes: 16 additions & 0 deletions ui/views/controls/native/native_view_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,22 @@ void NativeViewHost::VisibilityChanged(View* starting_from, bool is_visible) {
Layout();
}

void NativeViewHost::OnSoftVisibilityChanged(bool visible) {
if (!native_view_ || !native_wrapper_.get())
return;

if (GetVisibleBounds().IsEmpty())
return;

// If the widget wasn't .e.g. minimized, hide and show would trigger
// PageVisibility API, enabling JS to save power while screen is locked.
if (visible) {
Layout();
} else {
native_wrapper_->HideWidget();
}
}

bool NativeViewHost::GetNeedsNotificationWhenVisibleBoundsChange() const {
// The native widget is placed relative to the root. As such, we need to
// know when the position of any ancestor changes, or our visibility relative
Expand Down
1 change: 1 addition & 0 deletions ui/views/controls/native/native_view_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class VIEWS_EXPORT NativeViewHost : public View {
void OnFocus() override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override;
void OnSoftVisibilityChanged(bool visible) override;

protected:
bool GetNeedsNotificationWhenVisibleBoundsChange() const override;
Expand Down
6 changes: 6 additions & 0 deletions ui/views/view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1893,6 +1893,12 @@ void View::PropagateNativeThemeChanged(const ui::NativeTheme* theme) {
OnNativeThemeChanged(theme);
}

void View::PropagateSoftVisibilityChanged(bool visible) {
for (int i = 0, count = child_count(); i < count; ++i)
child_at(i)->PropagateSoftVisibilityChanged(visible);
OnSoftVisibilityChanged(visible);
}

// Size and disposition --------------------------------------------------------

void View::PropagateVisibilityNotifications(View* start, bool is_visible) {
Expand Down
4 changes: 4 additions & 0 deletions ui/views/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// FocusManager manages this view.
virtual void NativeViewHierarchyChanged();

virtual void OnSoftVisibilityChanged(bool visible) {}

// Painting ------------------------------------------------------------------

// Responsible for calling Paint() on child Views. Override to control the
Expand Down Expand Up @@ -1285,6 +1287,8 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// VisibilityChanged().
void VisibilityChangedImpl(View* starting_from, bool is_visible);

void PropagateSoftVisibilityChanged(bool visible);

// Responsible for propagating bounds change notifications to relevant
// views.
void BoundsChanged(const gfx::Rect& previous_bounds);
Expand Down
4 changes: 4 additions & 0 deletions ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,10 @@ void DesktopWindowTreeHostWin::HandleVisibilityChanged(bool visible) {
native_widget_delegate_->OnNativeWidgetVisibilityChanged(visible);
}

void DesktopWindowTreeHostWin::HandleSoftVisibilityChanged(bool visible) {
native_widget_delegate_->OnSoftVisibilityChanged(visible);
}

void DesktopWindowTreeHostWin::HandleClientSizeChanged(
const gfx::Size& new_size) {
if (dispatcher())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
void HandleWindowSizeChanging() override;
void HandleWindowSizeChanged() override;
void HandleWindowScaleFactorChanged(float window_scale_factor) override;
void HandleSoftVisibilityChanged(bool visible) override;

Widget* GetWidget();
const Widget* GetWidget() const;
Expand Down
8 changes: 8 additions & 0 deletions ui/views/widget/native_widget_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ class VIEWS_EXPORT NativeWidgetDelegate {
// Called when the window is shown/hidden.
virtual void OnNativeWidgetVisibilityChanged(bool visible) = 0;

// Some OSs (e.g. Windows and Linux) don't mark windows as hiden on screen
// lock or when other opaque windows fully cover them.
// Note that e.g. OSX and Android do this while Windows and Linux don't.
// OnSoftVisibilityChanged enables that OS window state is kept as is (on
// Linux and Windows) and that e.g. power saving PageVisibility API is still
// properly triggered.
virtual void OnSoftVisibilityChanged(bool visible) = 0;

// Called when the native widget is created.
// The |desktop_widget| bool is true for widgets created in the desktop and
// false for widgets created in the shell.
Expand Down
5 changes: 5 additions & 0 deletions ui/views/widget/widget.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,11 @@ void Widget::OnNativeWidgetVisibilityChanged(bool visible) {
root->layer()->SetVisible(visible);
}

void Widget::OnSoftVisibilityChanged(bool visible) {
if (View* root = GetRootView())
root->PropagateSoftVisibilityChanged(visible);
}

void Widget::OnNativeWidgetCreated(bool desktop_widget) {
if (is_top_level())
focus_manager_.reset(FocusManagerFactory::Create(this, desktop_widget));
Expand Down
1 change: 1 addition & 0 deletions ui/views/widget/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
void OnNativeBlur() override;
void OnNativeWidgetVisibilityChanging(bool visible) override;
void OnNativeWidgetVisibilityChanged(bool visible) override;
void OnSoftVisibilityChanged(bool visible) override;
void OnNativeWidgetCreated(bool desktop_widget) override;
void OnNativeWidgetDestroying() override;
void OnNativeWidgetDestroyed() override;
Expand Down
8 changes: 7 additions & 1 deletion ui/views/win/hwnd_message_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2404,8 +2404,14 @@ void HWNDMessageHandler::OnWindowPosChanged(WINDOWPOS* window_pos) {
void HWNDMessageHandler::OnSessionChange(WPARAM status_code) {
// Direct3D presents are ignored while the screen is locked, so force the
// window to be redrawn on unlock.
if (status_code == WTS_SESSION_UNLOCK)
if (status_code == WTS_SESSION_UNLOCK) {
ForceRedrawWindow(10);
if (IsVisible())
delegate_->HandleSoftVisibilityChanged(true);
} else if (status_code == WTS_SESSION_LOCK) {
if (IsVisible())
delegate_->HandleSoftVisibilityChanged(false);
}
}

void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) {
Expand Down
6 changes: 6 additions & 0 deletions ui/views/win/hwnd_message_handler_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
// Called when the window's visibility changed. |visible| holds the new state.
virtual void HandleVisibilityChanged(bool visible) = 0;

// Called when the "calculated" window's visibility changed.
// OS doesn't mark windows hidden on screen lock or when other opaque windows
// cover them.
// |visible| holds the new state.
virtual void HandleSoftVisibilityChanged(bool visible) = 0;

// Called when the window's client size changed. |new_size| holds the new
// size.
virtual void HandleClientSizeChanged(const gfx::Size& new_size) = 0;
Expand Down

0 comments on commit 8754d66

Please sign in to comment.