Add "stylus-tools" Wayland protocol.
This protocol specifies a set of interfaces to control the behavior
of a stylus tool, a special kind of window allowing the user to
explore, annotate or manipulate on-screen content.
The first applications of that protocol are:
1. Exclude the stylus tool window from for a voice interaction
screenshot (implemented in this CL).
2. Only handle stylus input in the stylus tool window and let all
other types of events pass through to the underlying windows
(to be implemented).
BUG=b:37640737
TEST=Invoke metalayer, check that the screenshot does not contain
stylus strokes.
Review-Url: https://codereview.chromium.org/2896943002
Cr-Commit-Position: refs/heads/master@{#474580}
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index 46cfc4a4..7649a08 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -26,6 +26,7 @@
#include "components/exo/surface_delegate.h"
#include "components/exo/surface_observer.h"
#include "third_party/khronos/GLES2/gl2.h"
+#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_targeter.h"
@@ -52,6 +53,10 @@
// window. If unset, no surface is associated with window.
DEFINE_UI_CLASS_PROPERTY_KEY(Surface*, kSurfaceKey, nullptr);
+// A property key to store whether the surface should only consume
+// stylus input events.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kStylusOnlyKey, false);
+
// Helper function that returns an iterator to the first entry in |list|
// with |key|.
template <typename T, typename U>
@@ -634,6 +639,14 @@
SetSurfaceHierarchyNeedsCommitToNewSurfaces();
}
+bool Surface::IsStylusOnly() {
+ return window_->GetProperty(kStylusOnlyKey);
+}
+
+void Surface::SetStylusOnly() {
+ window_->SetProperty(kStylusOnlyKey, true);
+}
+
////////////////////////////////////////////////////////////////////////////////
// ui::ContextFactoryObserver overrides:
diff --git a/components/exo/surface.h b/components/exo/surface.h
index ae85eca8c..0abd511 100644
--- a/components/exo/surface.h
+++ b/components/exo/surface.h
@@ -200,6 +200,12 @@
// Returns the active contents size.
gfx::Size content_size() const { return content_size_; }
+ // Returns true if the associated window is in 'stylus-only' mode.
+ bool IsStylusOnly();
+
+ // Enables 'stylus-only' mode for the associated window.
+ void SetStylusOnly();
+
// Overridden from ui::ContextFactoryObserver:
void OnLostResources() override;
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn
index 2b09104..e93a234 100644
--- a/components/exo/wayland/BUILD.gn
+++ b/components/exo/wayland/BUILD.gn
@@ -44,6 +44,7 @@
"//third_party/wayland-protocols:remote_shell_protocol",
"//third_party/wayland-protocols:secure_output_protocol",
"//third_party/wayland-protocols:stylus_protocol",
+ "//third_party/wayland-protocols:stylus_tools_protocol",
"//third_party/wayland-protocols:viewporter_protocol",
"//third_party/wayland-protocols:vsync_feedback_protocol",
"//third_party/wayland-protocols:xdg_shell_protocol",
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index 09942962..e541591d 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -15,6 +15,7 @@
#include <secure-output-unstable-v1-server-protocol.h>
#include <stddef.h>
#include <stdint.h>
+#include <stylus-tools-unstable-v1-server-protocol.h>
#include <stylus-unstable-v1-server-protocol.h>
#include <stylus-unstable-v2-server-protocol.h>
#include <viewporter-server-protocol.h>
@@ -164,6 +165,10 @@
// to ignore the activation event originated by creation.
DEFINE_UI_CLASS_PROPERTY_KEY(bool, kIgnoreWindowActivated, true);
+// A property key containing a boolean set to true if the stylus_tool
+// object is associated with a window.
+DEFINE_UI_CLASS_PROPERTY_KEY(bool, kSurfaceHasStylusToolKey, false);
+
wl_resource* GetSurfaceResource(Surface* surface) {
return surface->GetProperty(kSurfaceResourceKey);
}
@@ -3839,6 +3844,87 @@
resource, &keyboard_configuration_implementation, data, nullptr);
}
+////////////////////////////////////////////////////////////////////////////////
+// stylus_tool interface:
+
+class StylusTool : public SurfaceObserver {
+ public:
+ explicit StylusTool(Surface* surface) : surface_(surface) {
+ surface_->AddSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasStylusToolKey, true);
+ }
+ ~StylusTool() override {
+ if (surface_) {
+ surface_->RemoveSurfaceObserver(this);
+ surface_->SetProperty(kSurfaceHasStylusToolKey, false);
+ }
+ }
+
+ void SetStylusOnly() { surface_->SetStylusOnly(); }
+
+ // Overridden from SurfaceObserver:
+ void OnSurfaceDestroying(Surface* surface) override {
+ surface->RemoveSurfaceObserver(this);
+ surface_ = nullptr;
+ }
+
+ private:
+ Surface* surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(StylusTool);
+};
+
+void stylus_tool_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void stylus_tool_set_stylus_only(wl_client* client, wl_resource* resource) {
+ GetUserDataAs<StylusTool>(resource)->SetStylusOnly();
+}
+
+const struct zcr_stylus_tool_v1_interface stylus_tool_implementation = {
+ stylus_tool_destroy, stylus_tool_set_stylus_only};
+
+////////////////////////////////////////////////////////////////////////////////
+// stylus_tools interface:
+
+void stylus_tools_destroy(wl_client* client, wl_resource* resource) {
+ wl_resource_destroy(resource);
+}
+
+void stylus_tools_get_stylus_tool(wl_client* client,
+ wl_resource* resource,
+ uint32_t id,
+ wl_resource* surface_resource) {
+ Surface* surface = GetUserDataAs<Surface>(surface_resource);
+ if (surface->GetProperty(kSurfaceHasStylusToolKey)) {
+ wl_resource_post_error(
+ resource, ZCR_STYLUS_TOOLS_V1_ERROR_STYLUS_TOOL_EXISTS,
+ "a stylus_tool object for that surface already exists");
+ return;
+ }
+
+ wl_resource* stylus_tool_resource =
+ wl_resource_create(client, &zcr_stylus_tool_v1_interface, 1, id);
+
+ SetImplementation(stylus_tool_resource, &stylus_tool_implementation,
+ base::MakeUnique<StylusTool>(surface));
+}
+
+const struct zcr_stylus_tools_v1_interface stylus_tools_implementation = {
+ stylus_tools_destroy, stylus_tools_get_stylus_tool};
+
+void bind_stylus_tools(wl_client* client,
+ void* data,
+ uint32_t version,
+ uint32_t id) {
+ wl_resource* resource =
+ wl_resource_create(client, &zcr_stylus_tools_v1_interface, 1, id);
+
+ wl_resource_set_implementation(resource, &stylus_tools_implementation, data,
+ nullptr);
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -3891,6 +3977,8 @@
bind_stylus_v2);
wl_global_create(wl_display_.get(), &zcr_keyboard_configuration_v1_interface,
2, display_, bind_keyboard_configuration);
+ wl_global_create(wl_display_.get(), &zcr_stylus_tools_v1_interface, 1,
+ display_, bind_stylus_tools);
}
Server::~Server() {}