Discussion:
[PATCH 1/2] xdg_shell: Add a new shell protocol.
(too old to reply)
antognolli
2013-07-19 19:42:13 UTC
Permalink
From: Rafael Antognolli <rafael.antognolli at intel.com>

xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
configure.ac | 1 +
protocol/Makefile.am | 3 +
protocol/xdg-surface.xml | 326 ++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/wayland-xdg-surface.pc.in | 10 ++
5 files changed, 341 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
create mode 100644 src/wayland-xdg-surface.pc.in

diff --git a/configure.ac b/configure.ac
index 536df9e..61579c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,6 +141,7 @@ AC_CONFIG_FILES([Makefile
src/wayland-server.pc
src/wayland-client.pc
src/wayland-scanner.pc
+ src/wayland-xdg-surface.pc
src/wayland-version.h
protocol/Makefile
tests/Makefile])
diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index 08690b3..69b5363 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1,4 @@
EXTRA_DIST = wayland.xml
+
+protocoldir = $(datadir)/wayland/protocol
+protocol_DATA = xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..de64018
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="create_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
+
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
+ </description>
+
+ <request name="pong">
+ <description summary="respond to a ping event">
+ A client must respond to a ping event with a pong request or
+ the client may be deemed unresponsive.
+ </description>
+ <arg name="serial" type="uint" summary="serial of the ping event"/>
+ </request>
+
+ <request name="move">
+ <description summary="start an interactive move">
+ Start a pointer-driven move of the surface.
+
+ This request must be used in response to a button press event.
+ The server may ignore move requests depending on the state of
+ the surface (e.g. fullscreen or maximized).
+ </description>
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ </request>
+
+ <enum name="resize">
+ <description summary="edge values for resizing">
+ These values are used to indicate which edge of a surface
+ is being dragged in a resize operation. The server may
+ use this information to adapt its behavior, e.g. choose
+ an appropriate cursor image.
+ </description>
+ <entry name="none" value="0"/>
+ <entry name="top" value="1"/>
+ <entry name="bottom" value="2"/>
+ <entry name="left" value="4"/>
+ <entry name="top_left" value="5"/>
+ <entry name="bottom_left" value="6"/>
+ <entry name="right" value="8"/>
+ <entry name="top_right" value="9"/>
+ <entry name="bottom_right" value="10"/>
+ </enum>
+
+ <request name="resize">
+ <description summary="start an interactive resize">
+ Start a pointer-driven resizing of the surface.
+
+ This request must be used in response to a button press event.
+ The server may ignore resize requests depending on the state of
+ the surface (e.g. fullscreen or maximized).
+ </description>
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
+ </request>
+
+ <request name="set_toplevel">
+ <description summary="make the surface a toplevel surface">
+ Map the surface as a toplevel surface.
+
+ A toplevel surface is not fullscreen, maximized or transient.
+ </description>
+ </request>
+
+ <enum name="transient">
+ <description summary="details of transient behaviour">
+ These flags specify details of the expected behaviour
+ of transient surfaces. Used in the set_transient request.
+ </description>
+ <entry name="inactive" value="0x1" summary="do not set keyboard focus"/>
+ </enum>
+
+ <request name="set_transient">
+ <description summary="make the surface a transient surface">
+ Map the surface relative to an existing surface.
+
+ The x and y arguments specify the locations of the upper left
+ corner of the surface relative to the upper left corner of the
+ parent surface, in surface local coordinates.
+
+ The flags argument controls details of the transient behaviour.
+ </description>
+
+ <arg name="parent" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="flags" type="uint"/>
+ </request>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface fullscreen">
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply default policy"/>
+ <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
+ <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
+ <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
+ </enum>
+
+ <request name="set_fullscreen">
+ <description summary="make the surface a fullscreen surface">
+ Map the surface as a fullscreen surface.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+ </description>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="set_popup">
+ <description summary="make the surface a popup surface">
+ Map the surface as a popup.
+
+ A popup surface is a transient surface with an added pointer
+ grab.
+
+ An existing implicit grab will be changed to owner-events mode,
+ and the popup grab will continue after the implicit grab ends
+ (i.e. releasing the mouse button does not cause the popup to
+ be unmapped).
+
+ The popup grab continues until the window is destroyed or a
+ mouse button is pressed in any other clients window. A click
+ in any of the clients surfaces is reported as normal, however,
+ clicks in other clients surfaces will be discarded and trigger
+ the callback.
+
+ The x and y arguments specify the locations of the upper left
+ corner of the surface relative to the upper left corner of the
+ parent surface, in surface local coordinates.
+ </description>
+
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="parent" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="flags" type="uint"/>
+ </request>
+
+ <request name="set_maximized">
+ <description summary="make the surface a maximized surface">
+ Map the surface as a maximized surface.
+
+ If an output parameter is given then the surface will be
+ maximized on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The compositor will reply with a configure event telling
+ the expected new surface size. The operation is completed
+ on the next buffer attach to this surface.
+
+ A maximized surface typically fills the entire output it is
+ bound to, except for desktop element such as panels. This is
+ the main difference between a maximized shell surface and a
+ fullscreen shell surface.
+
+ The details depend on the compositor implementation.
+ </description>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <event name="ping">
+ <description summary="ping client">
+ Ping a client to check if it is receiving events and sending
+ requests. A client is expected to reply with a pong request.
+ </description>
+ <arg name="serial" type="uint"/>
+ </event>
+
+ <event name="configure">
+ <description summary="suggest resize">
+ The configure event asks the client to resize its surface.
+
+ The size is a hint, in the sense that the client is free to
+ ignore it if it doesn't resize, pick a smaller size (to
+ satisfy aspect ratio or resize in steps of NxM pixels).
+
+ The edges parameter provides a hint about how the surface
+ was resized. The client may use this information to decide
+ how to adjust its content to the new size (e.g. a scrolling
+ area might adjust its content position to leave the viewable
+ content unmoved).
+
+ The client is free to dismiss all but the last configure
+ event it received.
+
+ The width and height arguments specify the size of the window
+ in surface local coordinates.
+ </description>
+
+ <arg name="edges" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+
+ <event name="popup_done">
+ <description summary="popup interaction is done">
+ The popup_done event is sent out when a popup grab is broken,
+ that is, when the users clicks a surface that doesn't belong
+ to the client owning the popup surface.
+ </description>
+ </event>
+ </interface>
+</protocol>
diff --git a/src/Makefile.am b/src/Makefile.am
index 4226f63..d8e4254 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,7 +33,7 @@ libwayland_client_la_SOURCES = \
wayland-client.c

pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = wayland-client.pc wayland-server.pc
+pkgconfig_DATA = wayland-client.pc wayland-server.pc wayland-xdg-surface.pc

AM_CPPFLAGS = $(FFI_CFLAGS)
AM_CFLAGS = $(GCC_CFLAGS)
diff --git a/src/wayland-xdg-surface.pc.in b/src/wayland-xdg-surface.pc.in
new file mode 100644
index 0000000..a708d53
--- /dev/null
+++ b/src/wayland-xdg-surface.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datadir=@datadir@
+protocoldir=${datadir}/wayland/protocol/
+
+Name: Wayland XDG Shell
+Description: XDG Shell protocol
+Version: 0.1
--
1.7.11.7
antognolli
2013-07-19 19:42:14 UTC
Permalink
From: Rafael Antognolli <rafael.antognolli at intel.com>

These functions only differ from the previous one because they request
that the given state is set, without changing the surface type, thus
removing any previously state that was set on it.

Both states can be used at the same time, and the states can be set or
unset independently.

NOTE: The original surface_set_maximized and surface_set_fullscreen
requests were removed.
---
protocol/xdg-surface.xml | 149 ++++++++++++++++++++++++++++-------------------
1 file changed, 89 insertions(+), 60 deletions(-)

diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
index de64018..7a73912 100644
--- a/protocol/xdg-surface.xml
+++ b/protocol/xdg-surface.xml
@@ -160,47 +160,6 @@
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>

- <request name="set_fullscreen">
- <description summary="make the surface a fullscreen surface">
- Map the surface as a fullscreen surface.
-
- If an output parameter is given then the surface will be made
- fullscreen on that output. If the client does not specify the
- output then the compositor will apply its policy - usually
- choosing the output on which the surface has the biggest surface
- area.
-
- The client may specify a method to resolve a size conflict
- between the output size and the surface size - this is provided
- through the method parameter.
-
- The framerate parameter is used only when the method is set
- to "driver", to indicate the preferred framerate. A value of 0
- indicates that the app does not care about framerate. The
- framerate is specified in mHz, that is framerate of 60000 is 60Hz.
-
- A method of "scale" or "driver" implies a scaling operation of
- the surface, either via a direct scaling operation or a change of
- the output mode. This will override any kind of output scaling, so
- that mapping a surface with a buffer size equal to the mode can
- fill the screen independent of buffer_scale.
-
- A method of "fill" means we don't scale up the buffer, however
- any output scale is applied. This means that you may run into
- an edge case where the application maps a buffer with the same
- size of the output mode but buffer_scale 1 (thus making a
- surface larger than the output). In this case it is allowed to
- downscale the results to fit the screen.
-
- The compositor must reply to this request with a configure event
- with the dimensions for the output on which the surface will
- be made fullscreen.
- </description>
- <arg name="method" type="uint"/>
- <arg name="framerate" type="uint"/>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
- </request>
-
<request name="set_popup">
<description summary="make the surface a popup surface">
Map the surface as a popup.
@@ -232,9 +191,34 @@
<arg name="flags" type="uint"/>
</request>

- <request name="set_maximized">
- <description summary="make the surface a maximized surface">
- Map the surface as a maximized surface.
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <request name="state_set_maximized">
+ <description summary="set the surface maximized state">
+ Set the surface state as maximized.

If an output parameter is given then the surface will be
maximized on that output. If the client does not specify the
@@ -252,33 +236,78 @@
fullscreen shell surface.

The details depend on the compositor implementation.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them.
</description>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>

- <request name="set_title">
- <description summary="set surface title">
- Set a short title for the surface.
+ <request name="state_unset_maximized">
+ <description summary="unset the surface maximized state">
+ Unset the surface as maximized.

- This string may be used to identify the surface in a task bar,
- window list, or other user interface elements provided by the
- compositor.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if fullscreen is still set, the surface
+ will be mapped as fullscreen, otherwise as a simple toplevel
+ surface).
+ </description>
+ </request>

- The string must be encoded in UTF-8.
+ <request name="state_set_fullscreen">
+ <description summary="set the surface fullscreen state">
+ Set the surface state as fullscreen.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them. It has precedence over maximized, and
+ the surface will be kept fullscreen until unset.
</description>
- <arg name="title" type="string"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>

- <request name="set_class">
- <description summary="set surface class">
- Set a class for the surface.
+ <request name="state_unset_fullscreen">
+ <description summary="unset the surface fullscreen state">
+ Unset the surface as maximized.

- The surface class identifies the general class of applications
- to which the surface belongs. A common convention is to use
- the file name (full path if non-standard location) of the
- applications .desktop file as the class.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if maximized is still set, the surface
+ will be mapped as maximized, otherwise as a simple toplevel
+ surface).
</description>
- <arg name="class_" type="string"/>
</request>

<event name="ping">
--
1.7.11.7
Pekka Paalanen
2013-10-08 07:07:55 UTC
Permalink
Hi,

sorry for a late reply, I'm still around 600 emails behind of
wayland-devel at ...


On Fri, 19 Jul 2013 16:42:13 -0300
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
configure.ac | 1 +
protocol/Makefile.am | 3 +
protocol/xdg-surface.xml | 326 ++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/wayland-xdg-surface.pc.in | 10 ++
5 files changed, 341 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
create mode 100644 src/wayland-xdg-surface.pc.in
diff --git a/configure.ac b/configure.ac
index 536df9e..61579c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,6 +141,7 @@ AC_CONFIG_FILES([Makefile
src/wayland-server.pc
src/wayland-client.pc
src/wayland-scanner.pc
+ src/wayland-xdg-surface.pc
src/wayland-version.h
protocol/Makefile
tests/Makefile])
diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index 08690b3..69b5363 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1,4 @@
EXTRA_DIST = wayland.xml
+
+protocoldir = $(datadir)/wayland/protocol
+protocol_DATA = xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..de64018
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="create_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
I know Rob suggested naming this as "create", but I think there is more
to think about.

wl_compositor.create_surface is definitely a "create" method, because
it creates a new independent object in both protocol and semantically
(a new surface).

Others like wl_shell.get_shell_surface, xdg_shell.create_xdg_surface,
wl_subcompositor.get_subsurface do create a new protocol object, but
not a new object semantically. These methods create an extension
interface to an existing "real" object, and this extension object
cannot function without the real object. That was my rationale for
using "get" in the method name: I am just retrieving a handle to the
extended interface.
Post by antognolli
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
Would it make sense to change this to follow the "inert protocol
object" idiom?

Instead of making the wrong destruction order prone to fatal protocol
errors, destroying the real object would only make the interface object
inert until destroyed. Would this be for the better allowing easier
code in toolkits, or for the worse due to tolerating sloppier(?) code?
Post by antognolli
+ </description>
I could not see a destructor request for this interface. I believe all
interfaces should have a destructor request defined, unless there is a
good reason to not define one (wl_callback is the rare example of
that). Otherwise it is possible that some later change makes us realize
we really do need it to avoid temporary leaking or other problems in the
compositor, like happened with some of the input related objects.

This extended interface (protocol object) gives the wl_surface a role
(doesn't it?). What should happen when the extended interface is
destroyed? Should the role be reset?

Would be nice to see consistency in behaviour between different
extension interfaces.


Thanks,
pq
Rafael Antognolli
2013-10-15 10:30:54 UTC
Permalink
Hi,
Post by Pekka Paalanen
Hi,
sorry for a late reply, I'm still around 600 emails behind of
wayland-devel at ...
On Fri, 19 Jul 2013 16:42:13 -0300
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
configure.ac | 1 +
protocol/Makefile.am | 3 +
protocol/xdg-surface.xml | 326 ++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/wayland-xdg-surface.pc.in | 10 ++
5 files changed, 341 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
create mode 100644 src/wayland-xdg-surface.pc.in
diff --git a/configure.ac b/configure.ac
index 536df9e..61579c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,6 +141,7 @@ AC_CONFIG_FILES([Makefile
src/wayland-server.pc
src/wayland-client.pc
src/wayland-scanner.pc
+ src/wayland-xdg-surface.pc
src/wayland-version.h
protocol/Makefile
tests/Makefile])
diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index 08690b3..69b5363 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1,4 @@
EXTRA_DIST = wayland.xml
+
+protocoldir = $(datadir)/wayland/protocol
+protocol_DATA = xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..de64018
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="create_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
I know Rob suggested naming this as "create", but I think there is more
to think about.
wl_compositor.create_surface is definitely a "create" method, because
it creates a new independent object in both protocol and semantically
(a new surface).
Others like wl_shell.get_shell_surface, xdg_shell.create_xdg_surface,
wl_subcompositor.get_subsurface do create a new protocol object, but
not a new object semantically. These methods create an extension
interface to an existing "real" object, and this extension object
cannot function without the real object. That was my rationale for
using "get" in the method name: I am just retrieving a handle to the
extended interface.
OK, it makes sense. Is there consensus about this? If so, I'll just
bring it back to get_xdg_surface.
Post by Pekka Paalanen
Post by antognolli
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
Would it make sense to change this to follow the "inert protocol
object" idiom?
Instead of making the wrong destruction order prone to fatal protocol
errors, destroying the real object would only make the interface object
inert until destroyed. Would this be for the better allowing easier
code in toolkits, or for the worse due to tolerating sloppier(?) code?
Not sure if it will help much from the toolkit point of view, I think
we can live with any solution (speaking for EFL).

But I can change it to the "inert protocol object" to keep consistency
with the other extensions.
Post by Pekka Paalanen
Post by antognolli
+ </description>
I could not see a destructor request for this interface. I believe all
interfaces should have a destructor request defined, unless there is a
good reason to not define one (wl_callback is the rare example of
that). Otherwise it is possible that some later change makes us realize
we really do need it to avoid temporary leaking or other problems in the
compositor, like happened with some of the input related objects.
Hmm... I don't know, I think I just copied what we had for wl_shell.
Should it have a destructor too?
Post by Pekka Paalanen
This extended interface (protocol object) gives the wl_surface a role
(doesn't it?). What should happen when the extended interface is
destroyed? Should the role be reset?
Would be nice to see consistency in behaviour between different
extension interfaces.
OK, will look at this.
Post by Pekka Paalanen
Thanks,
pq
--
Rafael Antognolli
Pekka Paalanen
2013-10-15 11:28:10 UTC
Permalink
On Tue, 15 Oct 2013 07:30:54 -0300
Post by Rafael Antognolli
Hi,
Post by Pekka Paalanen
Hi,
sorry for a late reply, I'm still around 600 emails behind of
wayland-devel at ...
On Fri, 19 Jul 2013 16:42:13 -0300
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
configure.ac | 1 +
protocol/Makefile.am | 3 +
protocol/xdg-surface.xml | 326 ++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/wayland-xdg-surface.pc.in | 10 ++
5 files changed, 341 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
create mode 100644 src/wayland-xdg-surface.pc.in
diff --git a/configure.ac b/configure.ac
index 536df9e..61579c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,6 +141,7 @@ AC_CONFIG_FILES([Makefile
src/wayland-server.pc
src/wayland-client.pc
src/wayland-scanner.pc
+ src/wayland-xdg-surface.pc
src/wayland-version.h
protocol/Makefile
tests/Makefile])
diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index 08690b3..69b5363 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1,4 @@
EXTRA_DIST = wayland.xml
+
+protocoldir = $(datadir)/wayland/protocol
+protocol_DATA = xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..de64018
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="create_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
I know Rob suggested naming this as "create", but I think there is more
to think about.
wl_compositor.create_surface is definitely a "create" method, because
it creates a new independent object in both protocol and semantically
(a new surface).
Others like wl_shell.get_shell_surface, xdg_shell.create_xdg_surface,
wl_subcompositor.get_subsurface do create a new protocol object, but
not a new object semantically. These methods create an extension
interface to an existing "real" object, and this extension object
cannot function without the real object. That was my rationale for
using "get" in the method name: I am just retrieving a handle to the
extended interface.
OK, it makes sense. Is there consensus about this? If so, I'll just
bring it back to get_xdg_surface.
I have only my opinion, and Rob disagreed, don't know about
others or concensus.
Post by Rafael Antognolli
Post by Pekka Paalanen
Post by antognolli
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
Would it make sense to change this to follow the "inert protocol
object" idiom?
Instead of making the wrong destruction order prone to fatal protocol
errors, destroying the real object would only make the interface object
inert until destroyed. Would this be for the better allowing easier
code in toolkits, or for the worse due to tolerating sloppier(?) code?
Not sure if it will help much from the toolkit point of view, I think
we can live with any solution (speaking for EFL).
But I can change it to the "inert protocol object" to keep consistency
with the other extensions.
Post by Pekka Paalanen
Post by antognolli
+ </description>
I could not see a destructor request for this interface. I believe all
interfaces should have a destructor request defined, unless there is a
good reason to not define one (wl_callback is the rare example of
that). Otherwise it is possible that some later change makes us realize
we really do need it to avoid temporary leaking or other problems in the
compositor, like happened with some of the input related objects.
Hmm... I don't know, I think I just copied what we had for wl_shell.
Should it have a destructor too?
In hindsight, it probably should. I guess roles were originally thought
to be "set once and forever" with the rationale that wl_surfaces are
cheap to create, so it wasn't really needed at the time. Nowadays when
we are getting an increasing number of extensions to wl_surface and
more state, it is becoming heavier. One could also argue whether
re-purposing a surface is needed at all, or a good practice.

Actually, we probably did not even have the concept of a role when
wl_shell_surface was designed.

Personally I feel that the rule "define a destructor request unless
there is a good reason not to" is a safe guideline. Again, just my
opinion.

At least every protocol object should have a way to get destroyed,
other than the client disconnecting. I bet everyone can agree on that,
but I would also add "without introducing tricky error conditions".
Post by Rafael Antognolli
Post by Pekka Paalanen
This extended interface (protocol object) gives the wl_surface a role
(doesn't it?). What should happen when the extended interface is
destroyed? Should the role be reset?
Would be nice to see consistency in behaviour between different
extension interfaces.
OK, will look at this.
As a rule of thumb, anything that sets weston_surface::configure is a
role. That should let you find them all, including pointer cursors and
dnd icons (IIRC these roles are reversable).


Thanks,
pq
Rafael Antognolli
2013-10-15 13:20:57 UTC
Permalink
Post by Pekka Paalanen
On Tue, 15 Oct 2013 07:30:54 -0300
Post by Rafael Antognolli
Hi,
Post by Pekka Paalanen
Hi,
sorry for a late reply, I'm still around 600 emails behind of
wayland-devel at ...
On Fri, 19 Jul 2013 16:42:13 -0300
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
configure.ac | 1 +
protocol/Makefile.am | 3 +
protocol/xdg-surface.xml | 326 ++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/wayland-xdg-surface.pc.in | 10 ++
5 files changed, 341 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
create mode 100644 src/wayland-xdg-surface.pc.in
diff --git a/configure.ac b/configure.ac
index 536df9e..61579c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,6 +141,7 @@ AC_CONFIG_FILES([Makefile
src/wayland-server.pc
src/wayland-client.pc
src/wayland-scanner.pc
+ src/wayland-xdg-surface.pc
src/wayland-version.h
protocol/Makefile
tests/Makefile])
diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index 08690b3..69b5363 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1,4 @@
EXTRA_DIST = wayland.xml
+
+protocoldir = $(datadir)/wayland/protocol
+protocol_DATA = xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..de64018
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="create_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
I know Rob suggested naming this as "create", but I think there is more
to think about.
wl_compositor.create_surface is definitely a "create" method, because
it creates a new independent object in both protocol and semantically
(a new surface).
Others like wl_shell.get_shell_surface, xdg_shell.create_xdg_surface,
wl_subcompositor.get_subsurface do create a new protocol object, but
not a new object semantically. These methods create an extension
interface to an existing "real" object, and this extension object
cannot function without the real object. That was my rationale for
using "get" in the method name: I am just retrieving a handle to the
extended interface.
OK, it makes sense. Is there consensus about this? If so, I'll just
bring it back to get_xdg_surface.
I have only my opinion, and Rob disagreed, don't know about
others or concensus.
So I'm waiting for more feedback. I'm keeping get_xdg_surface for now.
Post by Pekka Paalanen
Post by Rafael Antognolli
Post by Pekka Paalanen
Post by antognolli
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
Would it make sense to change this to follow the "inert protocol
object" idiom?
Instead of making the wrong destruction order prone to fatal protocol
errors, destroying the real object would only make the interface object
inert until destroyed. Would this be for the better allowing easier
code in toolkits, or for the worse due to tolerating sloppier(?) code?
Not sure if it will help much from the toolkit point of view, I think
we can live with any solution (speaking for EFL).
But I can change it to the "inert protocol object" to keep consistency
with the other extensions.
Post by Pekka Paalanen
Post by antognolli
+ </description>
I could not see a destructor request for this interface. I believe all
interfaces should have a destructor request defined, unless there is a
good reason to not define one (wl_callback is the rare example of
that). Otherwise it is possible that some later change makes us realize
we really do need it to avoid temporary leaking or other problems in the
compositor, like happened with some of the input related objects.
Hmm... I don't know, I think I just copied what we had for wl_shell.
Should it have a destructor too?
In hindsight, it probably should. I guess roles were originally thought
to be "set once and forever" with the rationale that wl_surfaces are
cheap to create, so it wasn't really needed at the time. Nowadays when
we are getting an increasing number of extensions to wl_surface and
more state, it is becoming heavier. One could also argue whether
re-purposing a surface is needed at all, or a good practice.
Actually, we probably did not even have the concept of a role when
wl_shell_surface was designed.
Personally I feel that the rule "define a destructor request unless
there is a good reason not to" is a safe guideline. Again, just my
opinion.
At least every protocol object should have a way to get destroyed,
other than the client disconnecting. I bet everyone can agree on that,
but I would also add "without introducing tricky error conditions".
OK, makes sense, I'm adding it too.
Post by Pekka Paalanen
Post by Rafael Antognolli
Post by Pekka Paalanen
This extended interface (protocol object) gives the wl_surface a role
(doesn't it?). What should happen when the extended interface is
destroyed? Should the role be reset?
Would be nice to see consistency in behaviour between different
extension interfaces.
OK, will look at this.
As a rule of thumb, anything that sets weston_surface::configure is a
role. That should let you find them all, including pointer cursors and
dnd icons (IIRC these roles are reversable).
Right, but what would happen if hte role is reset? From the docs,
subsurfaces are unmapped if the interface is destroyed. Should we do
the same in the xdg_surface case?
--
Rafael Antognolli
Pekka Paalanen
2013-10-15 13:44:27 UTC
Permalink
On Tue, 15 Oct 2013 10:20:57 -0300
Post by Rafael Antognolli
Post by Pekka Paalanen
On Tue, 15 Oct 2013 07:30:54 -0300
Post by Rafael Antognolli
Hi,
Post by Pekka Paalanen
Hi,
On Fri, 19 Jul 2013 16:42:13 -0300
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
configure.ac | 1 +
protocol/Makefile.am | 3 +
protocol/xdg-surface.xml | 326 ++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/wayland-xdg-surface.pc.in | 10 ++
5 files changed, 341 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
create mode 100644 src/wayland-xdg-surface.pc.in
...
Post by Rafael Antognolli
Post by Pekka Paalanen
Post by Rafael Antognolli
Post by Pekka Paalanen
This extended interface (protocol object) gives the wl_surface a role
(doesn't it?). What should happen when the extended interface is
destroyed? Should the role be reset?
Would be nice to see consistency in behaviour between different
extension interfaces.
OK, will look at this.
As a rule of thumb, anything that sets weston_surface::configure is a
role. That should let you find them all, including pointer cursors and
dnd icons (IIRC these roles are reversable).
Right, but what would happen if hte role is reset? From the docs,
subsurfaces are unmapped if the interface is destroyed. Should we do
the same in the xdg_surface case?
Yes. On the desktop, role-less surfaces are never visible. A compositor
does not know how to show a surface without a role. In the Weston code
base this is evident from role-less surfaces not having a function to
configure them on screen.


Thanks,
pq
antognolli
2013-10-15 15:05:04 UTC
Permalink
From: Rafael Antognolli <rafael.antognolli at intel.com>

xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
protocol/Makefile.am | 2 +-
protocol/xdg-surface.xml | 336 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 337 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml

diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index cc9cd1c..5f26d77 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1 @@
-dist_pkgdata_DATA = wayland.xml
+dist_pkgdata_DATA = wayland.xml xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..4d2cc1b
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="get_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
+
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="remove xdg_surface interface">
+ The xdg_surface interface is removed from the wl_surface object
+ that was turned into a xdg_surface with
+ xdg_shell.get_xdg_surface request. The xdg_surface properties,
+ like maximized and fullscreen, are lost. The wl_surface loses
+ its role as a xdg_surface. The wl_surface is unmapped.
+ </description>
+ </request>
+
+ <request name="pong">
+ <description summary="respond to a ping event">
+ A client must respond to a ping event with a pong request or
+ the client may be deemed unresponsive.
+ </description>
+ <arg name="serial" type="uint" summary="serial of the ping event"/>
+ </request>
+
+ <request name="move">
+ <description summary="start an interactive move">
+ Start a pointer-driven move of the surface.
+
+ This request must be used in response to a button press event.
+ The server may ignore move requests depending on the state of
+ the surface (e.g. fullscreen or maximized).
+ </description>
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ </request>
+
+ <enum name="resize">
+ <description summary="edge values for resizing">
+ These values are used to indicate which edge of a surface
+ is being dragged in a resize operation. The server may
+ use this information to adapt its behavior, e.g. choose
+ an appropriate cursor image.
+ </description>
+ <entry name="none" value="0"/>
+ <entry name="top" value="1"/>
+ <entry name="bottom" value="2"/>
+ <entry name="left" value="4"/>
+ <entry name="top_left" value="5"/>
+ <entry name="bottom_left" value="6"/>
+ <entry name="right" value="8"/>
+ <entry name="top_right" value="9"/>
+ <entry name="bottom_right" value="10"/>
+ </enum>
+
+ <request name="resize">
+ <description summary="start an interactive resize">
+ Start a pointer-driven resizing of the surface.
+
+ This request must be used in response to a button press event.
+ The server may ignore resize requests depending on the state of
+ the surface (e.g. fullscreen or maximized).
+ </description>
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
+ </request>
+
+ <request name="set_toplevel">
+ <description summary="make the surface a toplevel surface">
+ Map the surface as a toplevel surface.
+
+ A toplevel surface is not fullscreen, maximized or transient.
+ </description>
+ </request>
+
+ <enum name="transient">
+ <description summary="details of transient behaviour">
+ These flags specify details of the expected behaviour
+ of transient surfaces. Used in the set_transient request.
+ </description>
+ <entry name="inactive" value="0x1" summary="do not set keyboard focus"/>
+ </enum>
+
+ <request name="set_transient">
+ <description summary="make the surface a transient surface">
+ Map the surface relative to an existing surface.
+
+ The x and y arguments specify the locations of the upper left
+ corner of the surface relative to the upper left corner of the
+ parent surface, in surface local coordinates.
+
+ The flags argument controls details of the transient behaviour.
+ </description>
+
+ <arg name="parent" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="flags" type="uint"/>
+ </request>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface fullscreen">
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply default policy"/>
+ <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
+ <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
+ <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
+ </enum>
+
+ <request name="set_fullscreen">
+ <description summary="make the surface a fullscreen surface">
+ Map the surface as a fullscreen surface.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+ </description>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="set_popup">
+ <description summary="make the surface a popup surface">
+ Map the surface as a popup.
+
+ A popup surface is a transient surface with an added pointer
+ grab.
+
+ An existing implicit grab will be changed to owner-events mode,
+ and the popup grab will continue after the implicit grab ends
+ (i.e. releasing the mouse button does not cause the popup to
+ be unmapped).
+
+ The popup grab continues until the window is destroyed or a
+ mouse button is pressed in any other clients window. A click
+ in any of the clients surfaces is reported as normal, however,
+ clicks in other clients surfaces will be discarded and trigger
+ the callback.
+
+ The x and y arguments specify the locations of the upper left
+ corner of the surface relative to the upper left corner of the
+ parent surface, in surface local coordinates.
+ </description>
+
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="parent" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="flags" type="uint"/>
+ </request>
+
+ <request name="set_maximized">
+ <description summary="make the surface a maximized surface">
+ Map the surface as a maximized surface.
+
+ If an output parameter is given then the surface will be
+ maximized on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The compositor will reply with a configure event telling
+ the expected new surface size. The operation is completed
+ on the next buffer attach to this surface.
+
+ A maximized surface typically fills the entire output it is
+ bound to, except for desktop element such as panels. This is
+ the main difference between a maximized shell surface and a
+ fullscreen shell surface.
+
+ The details depend on the compositor implementation.
+ </description>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <event name="ping">
+ <description summary="ping client">
+ Ping a client to check if it is receiving events and sending
+ requests. A client is expected to reply with a pong request.
+ </description>
+ <arg name="serial" type="uint"/>
+ </event>
+
+ <event name="configure">
+ <description summary="suggest resize">
+ The configure event asks the client to resize its surface.
+
+ The size is a hint, in the sense that the client is free to
+ ignore it if it doesn't resize, pick a smaller size (to
+ satisfy aspect ratio or resize in steps of NxM pixels).
+
+ The edges parameter provides a hint about how the surface
+ was resized. The client may use this information to decide
+ how to adjust its content to the new size (e.g. a scrolling
+ area might adjust its content position to leave the viewable
+ content unmoved).
+
+ The client is free to dismiss all but the last configure
+ event it received.
+
+ The width and height arguments specify the size of the window
+ in surface local coordinates.
+ </description>
+
+ <arg name="edges" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+
+ <event name="popup_done">
+ <description summary="popup interaction is done">
+ The popup_done event is sent out when a popup grab is broken,
+ that is, when the users clicks a surface that doesn't belong
+ to the client owning the popup surface.
+ </description>
+ </event>
+ </interface>
+</protocol>
--
1.8.3.1
antognolli
2013-10-15 15:05:05 UTC
Permalink
From: Rafael Antognolli <rafael.antognolli at intel.com>

These functions only differ from the previous one because they request
that the given state is set, without changing the surface type, thus
removing any previously state that was set on it.

Both states can be used at the same time, and the states can be set or
unset independently.

NOTE: The original surface_set_maximized and surface_set_fullscreen
requests were removed.
---
protocol/xdg-surface.xml | 149 ++++++++++++++++++++++++++++-------------------
1 file changed, 89 insertions(+), 60 deletions(-)

diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
index 4d2cc1b..b224fee 100644
--- a/protocol/xdg-surface.xml
+++ b/protocol/xdg-surface.xml
@@ -170,47 +170,6 @@
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>

- <request name="set_fullscreen">
- <description summary="make the surface a fullscreen surface">
- Map the surface as a fullscreen surface.
-
- If an output parameter is given then the surface will be made
- fullscreen on that output. If the client does not specify the
- output then the compositor will apply its policy - usually
- choosing the output on which the surface has the biggest surface
- area.
-
- The client may specify a method to resolve a size conflict
- between the output size and the surface size - this is provided
- through the method parameter.
-
- The framerate parameter is used only when the method is set
- to "driver", to indicate the preferred framerate. A value of 0
- indicates that the app does not care about framerate. The
- framerate is specified in mHz, that is framerate of 60000 is 60Hz.
-
- A method of "scale" or "driver" implies a scaling operation of
- the surface, either via a direct scaling operation or a change of
- the output mode. This will override any kind of output scaling, so
- that mapping a surface with a buffer size equal to the mode can
- fill the screen independent of buffer_scale.
-
- A method of "fill" means we don't scale up the buffer, however
- any output scale is applied. This means that you may run into
- an edge case where the application maps a buffer with the same
- size of the output mode but buffer_scale 1 (thus making a
- surface larger than the output). In this case it is allowed to
- downscale the results to fit the screen.
-
- The compositor must reply to this request with a configure event
- with the dimensions for the output on which the surface will
- be made fullscreen.
- </description>
- <arg name="method" type="uint"/>
- <arg name="framerate" type="uint"/>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
- </request>
-
<request name="set_popup">
<description summary="make the surface a popup surface">
Map the surface as a popup.
@@ -242,9 +201,34 @@
<arg name="flags" type="uint"/>
</request>

- <request name="set_maximized">
- <description summary="make the surface a maximized surface">
- Map the surface as a maximized surface.
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <request name="state_set_maximized">
+ <description summary="set the surface maximized state">
+ Set the surface state as maximized.

If an output parameter is given then the surface will be
maximized on that output. If the client does not specify the
@@ -262,33 +246,78 @@
fullscreen shell surface.

The details depend on the compositor implementation.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them.
</description>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>

- <request name="set_title">
- <description summary="set surface title">
- Set a short title for the surface.
+ <request name="state_unset_maximized">
+ <description summary="unset the surface maximized state">
+ Unset the surface as maximized.

- This string may be used to identify the surface in a task bar,
- window list, or other user interface elements provided by the
- compositor.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if fullscreen is still set, the surface
+ will be mapped as fullscreen, otherwise as a simple toplevel
+ surface).
+ </description>
+ </request>

- The string must be encoded in UTF-8.
+ <request name="state_set_fullscreen">
+ <description summary="set the surface fullscreen state">
+ Set the surface state as fullscreen.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them. It has precedence over maximized, and
+ the surface will be kept fullscreen until unset.
</description>
- <arg name="title" type="string"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>

- <request name="set_class">
- <description summary="set surface class">
- Set a class for the surface.
+ <request name="state_unset_fullscreen">
+ <description summary="unset the surface fullscreen state">
+ Unset the surface as maximized.

- The surface class identifies the general class of applications
- to which the surface belongs. A common convention is to use
- the file name (full path if non-standard location) of the
- applications .desktop file as the class.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if maximized is still set, the surface
+ will be mapped as maximized, otherwise as a simple toplevel
+ surface).
</description>
- <arg name="class_" type="string"/>
</request>

<event name="ping">
--
1.8.3.1
Kristian Høgsberg
2013-10-16 05:53:10 UTC
Permalink
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
These functions only differ from the previous one because they request
that the given state is set, without changing the surface type, thus
removing any previously state that was set on it.
Both states can be used at the same time, and the states can be set or
unset independently.
NOTE: The original surface_set_maximized and surface_set_fullscreen
requests were removed.
Hi Rafael,

Just to keep the list in the loop - we talked about how to send out
these patches and I think it's clearer if we just work on one patch
that adds the xdg-shell.xml file in one go instead of these two
patches.

Much of the discussion on the list around xdg_shell has been about the
surface states and how the server can initiate maximize or minimize
etc. I think we mostly have consensus there, so I want to bring up a
few other points/ideas for xdg_shell. These are a little un-edited,
but it's late here and I just want to start the discussion:

- move/resize needs cursor_surface arg to avoid mismatch between
hover cursor and resize/move cursor.

- transient for shouldn't take position.

- We should add a _NET_WM_STATE_DEMANDS_ATTENTION equivalent

- New keyboard focus protocol: instead of active surface meaning
"has keyboard focus" we need something that works in a touch-only
environment and we need a more generic way to create surfaces that
don't take keyboard focus. I propose a new xdg_surface.activate event
that indicates that the surface has been activated (by clicking or
touching or alt-tabbing to it (or hovering in case of sloppy focus)).
When a surface is "the active surface", the client can choose to
assign kb focus (xdg_surface.take_keyboard_focus) to any of its
surfaces.

- We need to solve stacking - how does a wayland shell raise an
applications and all its surfaces correctly. The two ideas I have are
either 1) let the client raise its surfaces when it's active (uses the
same xdg_surface.activate event as above) and just let the client
control which surfaces to raise and in which order in response to
being activated or 2) let the client describe above/below relation
between its surfaces and make sure the shell respects these
constraints when raising a surface (eg, toolbars above documents, but
no relation between individual toolbar surfaces or doc surfaces.
Raising a document raises all the toolbox surfaces to be on top, but
doesn't affect other documents and preserves the stacking order of the
toolbox surface).

- always on top, sticky; I think these are straight forward,
they're just flags an application can set.

- If a compositor initiates a maximize, it should immediately
followed the event by a configure event so that the client does not
need to wait for a configure event in response to set_maximized. just
a subtle tweak to avoid eliminate roundtrip.

Kristian
Post by antognolli
protocol/xdg-surface.xml | 149 ++++++++++++++++++++++++++++-------------------
1 file changed, 89 insertions(+), 60 deletions(-)
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
index 4d2cc1b..b224fee 100644
--- a/protocol/xdg-surface.xml
+++ b/protocol/xdg-surface.xml
@@ -170,47 +170,6 @@
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>
- <request name="set_fullscreen">
- <description summary="make the surface a fullscreen surface">
- Map the surface as a fullscreen surface.
-
- If an output parameter is given then the surface will be made
- fullscreen on that output. If the client does not specify the
- output then the compositor will apply its policy - usually
- choosing the output on which the surface has the biggest surface
- area.
-
- The client may specify a method to resolve a size conflict
- between the output size and the surface size - this is provided
- through the method parameter.
-
- The framerate parameter is used only when the method is set
- to "driver", to indicate the preferred framerate. A value of 0
- indicates that the app does not care about framerate. The
- framerate is specified in mHz, that is framerate of 60000 is 60Hz.
-
- A method of "scale" or "driver" implies a scaling operation of
- the surface, either via a direct scaling operation or a change of
- the output mode. This will override any kind of output scaling, so
- that mapping a surface with a buffer size equal to the mode can
- fill the screen independent of buffer_scale.
-
- A method of "fill" means we don't scale up the buffer, however
- any output scale is applied. This means that you may run into
- an edge case where the application maps a buffer with the same
- size of the output mode but buffer_scale 1 (thus making a
- surface larger than the output). In this case it is allowed to
- downscale the results to fit the screen.
-
- The compositor must reply to this request with a configure event
- with the dimensions for the output on which the surface will
- be made fullscreen.
- </description>
- <arg name="method" type="uint"/>
- <arg name="framerate" type="uint"/>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
- </request>
-
<request name="set_popup">
<description summary="make the surface a popup surface">
Map the surface as a popup.
@@ -242,9 +201,34 @@
<arg name="flags" type="uint"/>
</request>
- <request name="set_maximized">
- <description summary="make the surface a maximized surface">
- Map the surface as a maximized surface.
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <request name="state_set_maximized">
+ <description summary="set the surface maximized state">
+ Set the surface state as maximized.
If an output parameter is given then the surface will be
maximized on that output. If the client does not specify the
@@ -262,33 +246,78 @@
fullscreen shell surface.
The details depend on the compositor implementation.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them.
</description>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
- <request name="set_title">
- <description summary="set surface title">
- Set a short title for the surface.
+ <request name="state_unset_maximized">
+ <description summary="unset the surface maximized state">
+ Unset the surface as maximized.
- This string may be used to identify the surface in a task bar,
- window list, or other user interface elements provided by the
- compositor.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if fullscreen is still set, the surface
+ will be mapped as fullscreen, otherwise as a simple toplevel
+ surface).
+ </description>
+ </request>
- The string must be encoded in UTF-8.
+ <request name="state_set_fullscreen">
+ <description summary="set the surface fullscreen state">
+ Set the surface state as fullscreen.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them. It has precedence over maximized, and
+ the surface will be kept fullscreen until unset.
</description>
- <arg name="title" type="string"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
- <request name="set_class">
- <description summary="set surface class">
- Set a class for the surface.
+ <request name="state_unset_fullscreen">
+ <description summary="unset the surface fullscreen state">
+ Unset the surface as maximized.
- The surface class identifies the general class of applications
- to which the surface belongs. A common convention is to use
- the file name (full path if non-standard location) of the
- applications .desktop file as the class.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if maximized is still set, the surface
+ will be mapped as maximized, otherwise as a simple toplevel
+ surface).
</description>
- <arg name="class_" type="string"/>
</request>
<event name="ping">
--
1.8.3.1
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Rafael Antognolli
2013-10-16 14:56:46 UTC
Permalink
Post by Kristian Høgsberg
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
These functions only differ from the previous one because they request
that the given state is set, without changing the surface type, thus
removing any previously state that was set on it.
Both states can be used at the same time, and the states can be set or
unset independently.
NOTE: The original surface_set_maximized and surface_set_fullscreen
requests were removed.
Hi Rafael,
Just to keep the list in the loop - we talked about how to send out
these patches and I think it's clearer if we just work on one patch
that adds the xdg-shell.xml file in one go instead of these two
patches.
OK, I merged the patches and sent them again, along with some other
Post by Kristian Høgsberg
Much of the discussion on the list around xdg_shell has been about the
surface states and how the server can initiate maximize or minimize
etc. I think we mostly have consensus there, so I want to bring up a
few other points/ideas for xdg_shell. These are a little un-edited,
- move/resize needs cursor_surface arg to avoid mismatch between
hover cursor and resize/move cursor.
I don' t understand exactly why, but I added a cursor_surface arg to
them anyway.
Post by Kristian Høgsberg
- transient for shouldn't take position.
Same here. Why shouldn't t it take the position? How are we supposed
to set the transient surface position then? Another method?
Post by Kristian Høgsberg
- We should add a _NET_WM_STATE_DEMANDS_ATTENTION equivalent
Ack, I added a "demands_attention" request. Is that enough, or do we
need more parameters?
Post by Kristian Høgsberg
- New keyboard focus protocol: instead of active surface meaning
"has keyboard focus" we need something that works in a touch-only
environment and we need a more generic way to create surfaces that
don't take keyboard focus. I propose a new xdg_surface.activate event
that indicates that the surface has been activated (by clicking or
touching or alt-tabbing to it (or hovering in case of sloppy focus)).
When a surface is "the active surface", the client can choose to
assign kb focus (xdg_surface.take_keyboard_focus) to any of its
surfaces.
Ack. I added both the event and the request that you mention. Please
see if they are enough.
Post by Kristian Høgsberg
- We need to solve stacking - how does a wayland shell raise an
applications and all its surfaces correctly. The two ideas I have are
either 1) let the client raise its surfaces when it's active (uses the
same xdg_surface.activate event as above) and just let the client
control which surfaces to raise and in which order in response to
being activated or 2) let the client describe above/below relation
between its surfaces and make sure the shell respects these
constraints when raising a surface (eg, toolbars above documents, but
no relation between individual toolbar surfaces or doc surfaces.
Raising a document raises all the toolbox surfaces to be on top, but
doesn't affect other documents and preserves the stacking order of the
toolbox surface).
OK, this is really complex. I'm going to think about it too, but the
second approach seems to complicate things a lot from the
client/toolkits point of view, IMHO. I left it out for now, so we can
discuss it better.
Post by Kristian Høgsberg
- always on top, sticky; I think these are straight forward,
they're just flags an application can set.
Done, and also added the minimized state. I changed always on top to a
layer thing, so one can set (depending on the parameter) if it's
always on top or always below.

I also added the events for these statuses. Accepting suggestions for
better names.
Post by Kristian Høgsberg
- If a compositor initiates a maximize, it should immediately
followed the event by a configure event so that the client does not
need to wait for a configure event in response to set_maximized. just
a subtle tweak to avoid eliminate roundtrip.
OK, but this is just an implementation thing, right? Do I have to
change anything in the protocol for this?

Thanks for the review,
Rafael
Post by Kristian Høgsberg
Post by antognolli
protocol/xdg-surface.xml | 149 ++++++++++++++++++++++++++++-------------------
1 file changed, 89 insertions(+), 60 deletions(-)
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
index 4d2cc1b..b224fee 100644
--- a/protocol/xdg-surface.xml
+++ b/protocol/xdg-surface.xml
@@ -170,47 +170,6 @@
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
</enum>
- <request name="set_fullscreen">
- <description summary="make the surface a fullscreen surface">
- Map the surface as a fullscreen surface.
-
- If an output parameter is given then the surface will be made
- fullscreen on that output. If the client does not specify the
- output then the compositor will apply its policy - usually
- choosing the output on which the surface has the biggest surface
- area.
-
- The client may specify a method to resolve a size conflict
- between the output size and the surface size - this is provided
- through the method parameter.
-
- The framerate parameter is used only when the method is set
- to "driver", to indicate the preferred framerate. A value of 0
- indicates that the app does not care about framerate. The
- framerate is specified in mHz, that is framerate of 60000 is 60Hz.
-
- A method of "scale" or "driver" implies a scaling operation of
- the surface, either via a direct scaling operation or a change of
- the output mode. This will override any kind of output scaling, so
- that mapping a surface with a buffer size equal to the mode can
- fill the screen independent of buffer_scale.
-
- A method of "fill" means we don't scale up the buffer, however
- any output scale is applied. This means that you may run into
- an edge case where the application maps a buffer with the same
- size of the output mode but buffer_scale 1 (thus making a
- surface larger than the output). In this case it is allowed to
- downscale the results to fit the screen.
-
- The compositor must reply to this request with a configure event
- with the dimensions for the output on which the surface will
- be made fullscreen.
- </description>
- <arg name="method" type="uint"/>
- <arg name="framerate" type="uint"/>
- <arg name="output" type="object" interface="wl_output" allow-null="true"/>
- </request>
-
<request name="set_popup">
<description summary="make the surface a popup surface">
Map the surface as a popup.
@@ -242,9 +201,34 @@
<arg name="flags" type="uint"/>
</request>
- <request name="set_maximized">
- <description summary="make the surface a maximized surface">
- Map the surface as a maximized surface.
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <request name="state_set_maximized">
+ <description summary="set the surface maximized state">
+ Set the surface state as maximized.
If an output parameter is given then the surface will be
maximized on that output. If the client does not specify the
@@ -262,33 +246,78 @@
fullscreen shell surface.
The details depend on the compositor implementation.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them.
</description>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
- <request name="set_title">
- <description summary="set surface title">
- Set a short title for the surface.
+ <request name="state_unset_maximized">
+ <description summary="unset the surface maximized state">
+ Unset the surface as maximized.
- This string may be used to identify the surface in a task bar,
- window list, or other user interface elements provided by the
- compositor.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if fullscreen is still set, the surface
+ will be mapped as fullscreen, otherwise as a simple toplevel
+ surface).
+ </description>
+ </request>
- The string must be encoded in UTF-8.
+ <request name="state_set_fullscreen">
+ <description summary="set the surface fullscreen state">
+ Set the surface state as fullscreen.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+
+ This state can be set while other surface states are still set,
+ and it won't unset them. It has precedence over maximized, and
+ the surface will be kept fullscreen until unset.
</description>
- <arg name="title" type="string"/>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
</request>
- <request name="set_class">
- <description summary="set surface class">
- Set a class for the surface.
+ <request name="state_unset_fullscreen">
+ <description summary="unset the surface fullscreen state">
+ Unset the surface as maximized.
- The surface class identifies the general class of applications
- to which the surface belongs. A common convention is to use
- the file name (full path if non-standard location) of the
- applications .desktop file as the class.
+ The surface will be mapped to the corresponding state that has
+ more precedence (e.g. if maximized is still set, the surface
+ will be mapped as maximized, otherwise as a simple toplevel
+ surface).
</description>
- <arg name="class_" type="string"/>
</request>
<event name="ping">
--
1.8.3.1
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
--
Rafael Antognolli
Bill Spitzak
2013-10-17 17:32:13 UTC
Permalink
Post by Kristian Høgsberg
- transient for shouldn't take position.
What? I think that is necessary. It is relative to the parent surface.
Post by Kristian Høgsberg
- New keyboard focus protocol: instead of active surface meaning
"has keyboard focus" we need something that works in a touch-only
environment and we need a more generic way to create surfaces that
don't take keyboard focus. I propose a new xdg_surface.activate event
that indicates that the surface has been activated (by clicking or
touching or alt-tabbing to it (or hovering in case of sloppy focus)).
When a surface is "the active surface", the client can choose to
assign kb focus (xdg_surface.take_keyboard_focus) to any of its
surfaces.
Please allow clients to take the active themselves, maybe with a
xdg_surface.take_active request, and clients can decide themselves
whether a click or hover activates them. The compositor should not
activate surfaces due to events done to the surface (it can still
activate them due to things like alt+tab shortcuts and due to the
current active surface being unmapped).

This will allow clients to decide not to activate themselves, to make
the rules vary depending on where the events happen, and so that
point-to-type is a per-client rule, not a global one.

Hostile clients will not be able to grab the active, as the active
request will contain an event id that triggered it, and the compositor
can ignore it if the event is not a keystroke or mouse event to that client.
Post by Kristian Høgsberg
- We need to solve stacking - how does a wayland shell raise an
applications and all its surfaces correctly. The two ideas I have are
either 1) let the client raise its surfaces when it's active (uses the
same xdg_surface.activate event as above) and just let the client
control which surfaces to raise and in which order in response to
being activated or 2) let the client describe above/below relation
between its surfaces and make sure the shell respects these
constraints when raising a surface (eg, toolbars above documents, but
no relation between individual toolbar surfaces or doc surfaces.
Raising a document raises all the toolbox surfaces to be on top, but
doesn't affect other documents and preserves the stacking order of the
toolbox surface).
I am in favor of a hybrid approach. Version 1 above should always work:
a client can make a bunch of surfaces, not communicate any relationship
information about them to the compositor, and always have complete
knowledge and control over what order they are composited in. It can
insure that top-to-bottom order of 3 surfaces is A,B,C by raising B and
then raising A. And the compositor must *NEVER* raise surfaces itself.
Surfaces are ONLY raised in response to a request from the client. This
means the client always knows exactly what order they are in.

However the compositor should also support a tree of parent
relationships between surfaces, which a client may choose to use. Each
surface has a "parent", which is either null or another surface. If
surface A has a parent of B, a raise of B will also raise A, and a
map/unmap of B will map/unmap A. A client can at any moment change the
parent of any surface to any other one except it can't make a loop,
changing the tree will not change the state or position of any surface
even if it is "wrong", the tree only controls what happens when requests
are made to parents.

The reasons for supporting the tree (rather than have the client do
everything) are:

1. Pagers and task switchers can use this tree to determine that a bunch
of surfaces are related

2. Compositors may be able to take advantage of knowledge that two
surfaces are 'stuck together' and will raise as a unit. In particular it
can take advantage of everything being done for subsurfaces.

3. Familiarity and resemblence to other window systems.

I believe these child surfaces and "subsurfaces" are EXACTLY the same
thing. The only difference is that raising a subsurface puts it just
above the top-most subsurface with the same parent, while raising a
non-subsurface puts it at the top of it's layer, above surfaces
belonging to other clients. Merging sub, transient, and popup surfaces
will simplify wayland and provide advantages to both that currently only
exist for one or the other.

Because nothing happens unless raise or map requests are made from the
client, the client is still in control. It can change the tree any way
it wants before doing a raise request.

The common example of a floating dialog over two main windows would be
accomplished by the client changing the parent of the dialog to the main
window it is raising. This ability to change the tree avoids the need to
send a directed acyclic graph to the compositor, vastly simplifying the
compositor api.
Jason Ekstrand
2013-10-21 23:52:16 UTC
Permalink
Post by Kristian Høgsberg
- transient for shouldn't take position.
What? I think that is necessary. It is relative to the parent surface.
- New keyboard focus protocol: instead of active surface meaning
Post by Kristian Høgsberg
"has keyboard focus" we need something that works in a touch-only
environment and we need a more generic way to create surfaces that
don't take keyboard focus. I propose a new xdg_surface.activate event
that indicates that the surface has been activated (by clicking or
touching or alt-tabbing to it (or hovering in case of sloppy focus)).
When a surface is "the active surface", the client can choose to
assign kb focus (xdg_surface.take_keyboard_**focus) to any of its
surfaces.
Please allow clients to take the active themselves, maybe with a
xdg_surface.take_active request, and clients can decide themselves whether
a click or hover activates them. The compositor should not activate
surfaces due to events done to the surface (it can still activate them due
to things like alt+tab shortcuts and due to the current active surface
being unmapped).
This will allow clients to decide not to activate themselves, to make the
rules vary depending on where the events happen, and so that point-to-type
is a per-client rule, not a global one.
Hostile clients will not be able to grab the active, as the active request
will contain an event id that triggered it, and the compositor can ignore
it if the event is not a keystroke or mouse event to that client.
I think I would disagree on this one. As an avid sloppy-focus user, I
really don't want apps arbitrarily deciding that they are click-to-focus.
While some things (look and feel) are entirely cosmetic, if how apps get
focus is app-dependent, it will drive users crazy. I think the bigger
issue here is to allow for different modes of focus.

I think the big thing here is that we need to allow for a distinction
between "active" and "raised" and the compositor should be in rough control
of both. I say rough because the client may want to raise additional
windows (such as toolbars) and it is impossible for the compositor to know
exactly what the client will want to raise. Therefore, I'm a big fan of
the compositor sending a request_raise event and the client responding with
a series of raise requests (similar to the method recommended for handling
window states).

Most window managers I've seen have three basic window focus models:
1. Click to focus
2. Focus follows mouse, click to raise
3. Focus follows mouse, click or hold mouse above window for a short time
to raise.

I think all of these are valuable and probably not going away. In
particular, the last one has some accessibility benefits. Whatever
protocol we come up with, we need to be able to handle all three. This
means that we need to be able to tell a window that it is active without
raising it.

Bill, Allow me to more directly respond to the suggestion for take_active
that you described above. The problem isn't so much a configuration
issue. More to the point, in order to support all three of the above
modes, we have to allow a client to get keyboard focus and raise to the top
without clicking. If things are handled in terms of take_active then
clients will be able to raise themselves if the user so much as brushes the
mouse across them. I don't think we should allow clients to do whatever
they want as soon as they get a mouse. There may be a way to solve this,
but it's not presenting itself immediately.
Post by Kristian Høgsberg
- We need to solve stacking - how does a wayland shell raise an
Post by Kristian Høgsberg
applications and all its surfaces correctly. The two ideas I have are
either 1) let the client raise its surfaces when it's active (uses the
same xdg_surface.activate event as above) and just let the client
control which surfaces to raise and in which order in response to
being activated or 2) let the client describe above/below relation
between its surfaces and make sure the shell respects these
constraints when raising a surface (eg, toolbars above documents, but
no relation between individual toolbar surfaces or doc surfaces.
Raising a document raises all the toolbox surfaces to be on top, but
doesn't affect other documents and preserves the stacking order of the
toolbox surface).
I am in favor of a hybrid approach. Version 1 above should always work: a
client can make a bunch of surfaces, not communicate any relationship
information about them to the compositor, and always have complete
knowledge and control over what order they are composited in. It can insure
that top-to-bottom order of 3 surfaces is A,B,C by raising B and then
raising A. And the compositor must *NEVER* raise surfaces itself. Surfaces
are ONLY raised in response to a request from the client. This means the
client always knows exactly what order they are in.
However the compositor should also support a tree of parent relationships
between surfaces, which a client may choose to use. Each surface has a
"parent", which is either null or another surface. If surface A has a
parent of B, a raise of B will also raise A, and a map/unmap of B will
map/unmap A. A client can at any moment change the parent of any surface to
any other one except it can't make a loop, changing the tree will not
change the state or position of any surface even if it is "wrong", the tree
only controls what happens when requests are made to parents.
The reasons for supporting the tree (rather than have the client do
1. Pagers and task switchers can use this tree to determine that a bunch
of surfaces are related
2. Compositors may be able to take advantage of knowledge that two
surfaces are 'stuck together' and will raise as a unit. In particular it
can take advantage of everything being done for subsurfaces.
3. Familiarity and resemblence to other window systems.
I would agree that some sort of a tree is probably a good idea if for no
other reason than it makes raising atomic. One idea would be to treat a
xdg_surface.raise request like a sort of commit. The client would make a
bunch of xdg_surface.place_above (or some other name) requests to build the
tree and then call xdg_surface.raise on the root of the tree to raise the
whole tree. After that we could probably discard the place_above
relationships and let the client rebuild them for the next raise. Not that
that's really necessary but, as long as we allow clients to modify stacking
at times other than a full activate/raise, I don't see how useful keeping
the tree would be all that useful.
Post by Kristian Høgsberg
I believe these child surfaces and "subsurfaces" are EXACTLY the same
thing. The only difference is that raising a subsurface puts it just above
the top-most subsurface with the same parent, while raising a
non-subsurface puts it at the top of it's layer, above surfaces belonging
to other clients. Merging sub, transient, and popup surfaces will simplify
wayland and provide advantages to both that currently only exist for one or
the other.
The problem here is that subsurfaces are a compositor-wide thing while
transient and popup are shell things. Popup involves extra pointer
symantics. (I still don't fully understand transient)
Post by Kristian Høgsberg
Because nothing happens unless raise or map requests are made from the
client, the client is still in control. It can change the tree any way it
wants before doing a raise request.
The common example of a floating dialog over two main windows would be
accomplished by the client changing the parent of the dialog to the main
window it is raising. This ability to change the tree avoids the need to
send a directed acyclic graph to the compositor, vastly simplifying the
compositor api.
Just a few quick thoughs. I'm sure I'll have more as the discussion goes
on.
--Jason Ekstrand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131021/e9ab43bf/attachment.html>
Bill Spitzak
2013-10-22 20:36:21 UTC
Permalink
Post by Jason Ekstrand
I think I would disagree on this one. As an avid sloppy-focus user, I
really don't want apps arbitrarily deciding that they are
click-to-focus. While some things (look and feel) are entirely
cosmetic, if how apps get focus is app-dependent, it will drive users
crazy. I think the bigger issue here is to allow for different modes of
focus.
I also use sloppy focus all the time, which is why I *want* my proposal.
I see it as the opposite: I am allowing a client to be sloppy focus
whether or not the compositor thinks it should be.

Also for any focus model, my primary concern is that I want to allow the
areas that cause the focus to change to not have to correspond to the
edges of surfaces. In sloppy-focus it could help a lot if you had to
point at the text box, rather than the toolbar or border or a control
panel, to get the focus.
Post by Jason Ekstrand
I think the big thing here is that we need to allow for a distinction
between "active" and "raised" and the compositor should be in rough
control of both. I say rough because the client may want to raise
additional windows (such as toolbars) and it is impossible for the
compositor to know exactly what the client will want to raise.
Therefore, I'm a big fan of the compositor sending a request_raise event
and the client responding with a series of raise requests (similar to
the method recommended for handling window states).
Yes I agree mostly. Absolutely "active" and "raised" must be
independent. However I now do not think there needs to be any difference
between "active" and the keyboard focus for a particular seat.

The compositor must NEVER NEVER NEVER either raise or activate a
surface. It can only send request events to the client. The client can
then produce actual raise and activate actions. The only thing a
compositor can do is ignore these if it thinks they are inappropriate.
Post by Jason Ekstrand
1. Click to focus
My proposal would allow the focus to change depending on what the user
clicks on.
Post by Jason Ekstrand
2. Focus follows mouse, click to raise
My proposal (and I think everybody's proposal) would allow the client to
decide if a click raised the window. In particular it would allow you to
hit buttons and select text without raising the window, but clicking to
move the insertion point or draw would raise it.
Post by Jason Ekstrand
3. Focus follows mouse, click or hold mouse above window for a short
time to raise.
I think again this could be client responsibility. Though I would have a
"hover event" sent from the compositor, so that the timeout can agree
between all clients.
Post by Jason Ekstrand
Bill, Allow me to more directly respond to the suggestion for
take_active that you described above. The problem isn't so much a
configuration issue. More to the point, in order to support all three
of the above modes, we have to allow a client to get keyboard focus and
raise to the top without clicking. If things are handled in terms of
take_active then clients will be able to raise themselves if the user so
much as brushes the mouse across them. I don't think we should allow
clients to do whatever they want as soon as they get a mouse. There may
be a way to solve this, but it's not presenting itself immediately.
To do sloppy focus, the client would respond to a mouse-enter event by
requesting activation/focus. I'm not sure why you don't think sloppy
focus works under what I propose.

Activation would *NOT* raise the surface, unless the client wants it to.
Post by Jason Ekstrand
I would agree that some sort of a tree is probably a good idea if for no
other reason than it makes raising atomic. One idea would be to treat a
xdg_surface.raise request like a sort of commit. The client would make
a bunch of xdg_surface.place_above (or some other name) requests to
build the tree and then call xdg_surface.raise on the root of the tree
to raise the whole tree. After that we could probably discard the
place_above relationships and let the client rebuild them for the next
raise. Not that that's really necessary but, as long as we allow
clients to modify stacking at times other than a full activate/raise, I
don't see how useful keeping the tree would be all that useful.
This is the first proposal I said, echoing Kristian's first proposal.
Basically the client is entirely in control. There really does not need
to be any tree, just an atomic sequence of raises with a commit. I think
this should always work in Wayland.

The "tree" I propose is so that pager clients can have a clear idea what
the relationship between surfaces are. The problem with current trees
such as in ICCCM is that they end up really really complex, because in
fact what is wanted is a directed acyclic graph (more than one parent
per surface, this is attempted with "window groups" in ICCCM). I propose
this be avoided by:

The client can always change the tree whether or not the surfaces are
mapped. Changing the tree has no visible effect even if the current
stacking is "wrong". Surfaces are only raised by requests from the
client, so the client can always rearrange the tree before raising.
Post by Jason Ekstrand
I believe these child surfaces and "subsurfaces" are EXACTLY the
same thing.
The problem here is that subsurfaces are a compositor-wide thing while
transient and popup are shell things. Popup involves extra pointer
symantics. (I still don't fully understand transient)
That's what I'm complaining about. Wayland currently has two
implementations of a lot of stuff, depending on whether it is a floating
window or subsurface, even though these look and act IDENTICAL unless
you manage to get another surface from another client in-between the
floating window and it's parent. That is bad design. And there is no
reason subsurfaces are denied the "extra pointer symantics", and no
reason floating windows are denied all the sync work done for
multi-client subsurfaces.

I am using the word "transient" to mean a surface that stays above it's
parent, but otherwise has no effect.

"popup" seems to mean an atomic mapping of the window and pointer grab,
and possibly automatic unmapping when clicked outside? I think Wayland
is being excessively complex. I think somehow doing the grab before the
map would work to make them atomic. Instead of unmapping, I would have a
press outside the grabbing surface followed by a release cancel the
grab, but only after reporting the events as normal to the grabbing
surface. And the "popup" is unmapped by the client, not because it lost
the grab. In any case there really should be no difference between
transients, popups, and clients grabbing the pointer.

And it would be really nice if all this worked for subsurfaces.
Jason Ekstrand
2013-10-23 00:59:03 UTC
Permalink
Post by Jason Ekstrand
I think I would disagree on this one. As an avid sloppy-focus user, I
Post by Jason Ekstrand
really don't want apps arbitrarily deciding that they are click-to-focus.
While some things (look and feel) are entirely cosmetic, if how apps get
focus is app-dependent, it will drive users crazy. I think the bigger
issue here is to allow for different modes of focus.
I also use sloppy focus all the time, which is why I *want* my proposal. I
see it as the opposite: I am allowing a client to be sloppy focus whether
or not the compositor thinks it should be.
Also for any focus model, my primary concern is that I want to allow the
areas that cause the focus to change to not have to correspond to the edges
of surfaces. In sloppy-focus it could help a lot if you had to point at the
text box, rather than the toolbar or border or a control panel, to get the
focus.
I see what you mean here. However, I think apps doing this will cause more
trouble than it's worth. One thing about current sloppy focus
implementations is that you can click anywhere in the window to raise it.
You want to change this. However, what happens if that window is partially
obscured. In your scheme, you would have to move the window so that the
magic text box is uncovered in order to raise it. As is, if I want to see
said text box, I click the window to raise it so I can get to the text box.
Post by Jason Ekstrand
I think the big thing here is that we need to allow for a distinction
Post by Jason Ekstrand
between "active" and "raised" and the compositor should be in rough control
of both. I say rough because the client may want to raise additional
windows (such as toolbars) and it is impossible for the compositor to know
exactly what the client will want to raise. Therefore, I'm a big fan of
the compositor sending a request_raise event and the client responding with
a series of raise requests (similar to the method recommended for handling
window states).
Yes I agree mostly. Absolutely "active" and "raised" must be independent.
However I now do not think there needs to be any difference between
"active" and the keyboard focus for a particular seat.
The compositor must NEVER NEVER NEVER either raise or activate a surface.
It can only send request events to the client. The client can then produce
actual raise and activate actions. The only thing a compositor can do is
ignore these if it thinks they are inappropriate.
I 100% agree with you here.
Post by Jason Ekstrand
Post by Jason Ekstrand
1. Click to focus
My proposal would allow the focus to change depending on what the user
clicks on.
2. Focus follows mouse, click to raise
My proposal (and I think everybody's proposal) would allow the client to
decide if a click raised the window. In particular it would allow you to
hit buttons and select text without raising the window, but clicking to
move the insertion point or draw would raise it.
Yes, I agree it would be nice if you could select text without raising the
window. However, I'd still like a way to raise it without having to click
a particular region. That's an interesting UI problem
Post by Jason Ekstrand
3. Focus follows mouse, click or hold mouse above window for a short
Post by Jason Ekstrand
time to raise.
I think again this could be client responsibility. Though I would have a
"hover event" sent from the compositor, so that the timeout can agree
between all clients.
Bill, Allow me to more directly respond to the suggestion for take_active
Post by Jason Ekstrand
that you described above. The problem isn't so much a configuration issue.
More to the point, in order to support all three of the above modes, we
have to allow a client to get keyboard focus and raise to the top without
clicking. If things are handled in terms of take_active then clients will
be able to raise themselves if the user so much as brushes the mouse across
them. I don't think we should allow clients to do whatever they want as
soon as they get a mouse. There may be a way to solve this, but it's not
presenting itself immediately.
To do sloppy focus, the client would respond to a mouse-enter event by
requesting activation/focus. I'm not sure why you don't think sloppy focus
works under what I propose.
Activation would *NOT* raise the surface, unless the client wants it to.
I think the issue here is that the compositor must allow an application to
raise. It must not raise unless instructed that it can by the compositor.
There also needs to be a consistent way for applications to know whether or
not they are allowed to raise. If the only rule is "you have to be active
to raise" then a client can "take active" as soon as they see mouse
movement and then raise immediately afterwards.

Perhaps we could allow for some more flexibility if there was a way for the
client to reject an activation. However, I still have the above fears.
Post by Jason Ekstrand
I would agree that some sort of a tree is probably a good idea if for no
Post by Jason Ekstrand
other reason than it makes raising atomic. One idea would be to treat a
xdg_surface.raise request like a sort of commit. The client would make a
bunch of xdg_surface.place_above (or some other name) requests to build the
tree and then call xdg_surface.raise on the root of the tree to raise the
whole tree. After that we could probably discard the place_above
relationships and let the client rebuild them for the next raise. Not that
that's really necessary but, as long as we allow clients to modify stacking
at times other than a full activate/raise, I don't see how useful keeping
the tree would be all that useful.
This is the first proposal I said, echoing Kristian's first proposal.
Basically the client is entirely in control. There really does not need to
be any tree, just an atomic sequence of raises with a commit. I think this
should always work in Wayland.
The "tree" I propose is so that pager clients can have a clear idea what
the relationship between surfaces are. The problem with current trees such
as in ICCCM is that they end up really really complex, because in fact what
is wanted is a directed acyclic graph (more than one parent per surface,
this is attempted with "window groups" in ICCCM). I propose this be avoided
The client can always change the tree whether or not the surfaces are
mapped. Changing the tree has no visible effect even if the current
stacking is "wrong". Surfaces are only raised by requests from the client,
so the client can always rearrange the tree before raising.
Yes, I like this. I don't think it's feasible to try and keep some crazy
DAG. As long as a client can atomically raise a bunch of windows we should
be ok. A tree, whether or not it persists after the raise, will accomplish
this.
Post by Jason Ekstrand
I believe these child surfaces and "subsurfaces" are EXACTLY the
Post by Jason Ekstrand
same thing.
The problem here is that subsurfaces are a compositor-wide thing while
transient and popup are shell things. Popup involves extra pointer
symantics. (I still don't fully understand transient)
That's what I'm complaining about. Wayland currently has two
implementations of a lot of stuff, depending on whether it is a floating
window or subsurface, even though these look and act IDENTICAL unless you
manage to get another surface from another client in-between the floating
window and it's parent. That is bad design. And there is no reason
subsurfaces are denied the "extra pointer symantics", and no reason
floating windows are denied all the sync work done for multi-client
subsurfaces.
I am using the word "transient" to mean a surface that stays above it's
parent, but otherwise has no effect.
"popup" seems to mean an atomic mapping of the window and pointer grab,
and possibly automatic unmapping when clicked outside? I think Wayland is
being excessively complex. I think somehow doing the grab before the map
would work to make them atomic. Instead of unmapping, I would have a press
outside the grabbing surface followed by a release cancel the grab, but
only after reporting the events as normal to the grabbing surface. And the
"popup" is unmapped by the client, not because it lost the grab. In any
case there really should be no difference between transients, popups, and
clients grabbing the pointer.
And it would be really nice if all this worked for subsurfaces.
I still don't think these *should* be the same. I understand that the
semantics are similar, particularly for popup windows. That said, Kristian
has talked about removing the coordinates from "transient". If we remove
the coordinates, then I'm not sure we even need "transient" as clients can
simply ensure that that window always gets raised with the parent.
Allowing clients to be in complete control of window stacking order (within
the client) would make a lot of things simpler.

Part of this is that I'm still not 100% happy with the fact that
subsurfaces don't get clipped to their parent. (However, my feelings on
subsurface design are off topic here). That said, If it were to change, it
would cause problems with using it for popups and things of the like.
Also, this would require all compositors supporting the xdg_shell to
support subsurfaces in order to have a useful shell. Right now,
subsurfaces are optional..
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131022/c1b90e8a/attachment.html>
Bill Spitzak
2013-10-23 03:46:16 UTC
Permalink
Post by Jason Ekstrand
I see what you mean here. However, I think apps doing this will cause
more trouble than it's worth. One thing about current sloppy focus
implementations is that you can click anywhere in the window to raise
it. You want to change this. However, what happens if that window is
partially obscured. In your scheme, you would have to move the window
so that the magic text box is uncovered in order to raise it. As is, if
I want to see said text box, I click the window to raise it so I can get
to the text box.
Yes, I agree it would be nice if you could select text without raising
the window. However, I'd still like a way to raise it without having to
click a particular region. That's an interesting UI problem
I think the clients can raise if the user clicks on a "dead" area where
the click serves no purpose. The most obvious is the window borders, but
also gaps between widgets and widgets that don't use click for anything
could raise the window.

It would still be possible for all the visible area of a surface to be
covered with buttons so there is nowhere to click to raise it. If this
is really a problem then perhaps the user holds down some shift key and
clicks?
Post by Jason Ekstrand
Perhaps we could allow for some more flexibility if there was a way for
the client to reject an activation. However, I still have the above fears.
Absolutely a client must be able to "reject an activation". This would
be just like raise and focus: the compositor can only send a request
event to the client. The client must respond with an activate request if
it really wants activation.

However I think this may mean there is no difference between activation
and having a particular seat's keyboard focus.
Post by Jason Ekstrand
Yes, I like this. I don't think it's feasible to try and keep some
crazy DAG. As long as a client can atomically raise a bunch of windows
we should be ok. A tree, whether or not it persists after the raise,
will accomplish this.
I think if the tree does not persist then it is identical to the "client
does a lot of raises atomically" version. This is however a possible
solution.

The only reason for the tree is so that other clients can examine it and
get some ideas about the relationship between surfaces. And also for
familiarity with other window systems. I think it may also be useful for
RDP to other window systems which may not have atomic sets of raises.
Post by Jason Ekstrand
I believe these child surfaces and "subsurfaces" are EXACTLY the
same thing.
I still don't think these *should* be the same. I understand that the
semantics are similar, particularly for popup windows. That said,
Kristian has talked about removing the coordinates from "transient".
Not clear what he is getting at there. If the client can't position a
popup menu in the correct location it is pretty useless. I suspect he is
using a different definition of "transient" than I am.
Post by Jason Ekstrand
Part of this is that I'm still not 100% happy with the fact that
subsurfaces don't get clipped to their parent.
I think clipping should be part of the buffer object. For instance a
block of shared memory can easily be "clipped" to a smaller buffer by
sending the correct stride and origin pointer. I hope (though I am
unsure) that this is possible with EGL buffers and other schemes being used.
Post by Jason Ekstrand
That said, If it were to change,
it would cause problems with using it for popups and things of the
like. Also, this would require all compositors supporting the xdg_shell
to support subsurfaces in order to have a useful shell. Right now,
subsurfaces are optional..
I believe that any compositor that can support the overlaid windows has
99% of the necessary code to support subwindows, and vice-versa. The
only difference is whether another surface can be inserted between them.
Jason Ekstrand
2013-10-23 20:20:52 UTC
Permalink
Post by Jason Ekstrand
I see what you mean here. However, I think apps doing this will cause
Post by Jason Ekstrand
more trouble than it's worth. One thing about current sloppy focus
implementations is that you can click anywhere in the window to raise
it. You want to change this. However, what happens if that window is
partially obscured. In your scheme, you would have to move the window
so that the magic text box is uncovered in order to raise it. As is, if
I want to see said text box, I click the window to raise it so I can get
to the text box.
Yes, I agree it would be nice if you could select text without raising
Post by Jason Ekstrand
the window. However, I'd still like a way to raise it without having to
click a particular region. That's an interesting UI problem
I think the clients can raise if the user clicks on a "dead" area where
the click serves no purpose. The most obvious is the window borders, but
also gaps between widgets and widgets that don't use click for anything
could raise the window.
It would still be possible for all the visible area of a surface to be
covered with buttons so there is nowhere to click to raise it. If this is
really a problem then perhaps the user holds down some shift key and clicks?
Perhaps we could allow for some more flexibility if there was a way for
Post by Jason Ekstrand
the client to reject an activation. However, I still have the above fears.
Absolutely a client must be able to "reject an activation". This would be
just like raise and focus: the compositor can only send a request event to
the client. The client must respond with an activate request if it really
wants activation.
However I think this may mean there is no difference between activation
and having a particular seat's keyboard focus.
At this point, I think I can propose a solution which should allow for
client control while still keeping the compositor in control:
1) The xdg_surface has a pare of activate/deactivate events. I think we
need more than keyboard focus here because the user may not have a physical
keyboard.
2) A request_raise event to which the client *can* respond with any number
of raise requests.
3) Both the request_raise and the activate events have a serial. If the
event corresponded to some user input (such as a mouse press) then the
serial will match that of the input event. Otherwise, it will have its own
serial.
Post by Jason Ekstrand
Yes, I like this. I don't think it's feasible to try and keep some
Post by Jason Ekstrand
crazy DAG. As long as a client can atomically raise a bunch of windows
we should be ok. A tree, whether or not it persists after the raise,
will accomplish this.
I think if the tree does not persist then it is identical to the "client
does a lot of raises atomically" version. This is however a possible
solution.
The only reason for the tree is so that other clients can examine it and
get some ideas about the relationship between surfaces. And also for
familiarity with other window systems. I think it may also be useful for
RDP to other window systems which may not have atomic sets of raises.
I believe these child surfaces and "subsurfaces" are
Post by Jason Ekstrand
EXACTLY the
same thing.
I still don't think these *should* be the same. I understand that the
semantics are similar, particularly for popup windows. That said,
Kristian has talked about removing the coordinates from "transient".
Not clear what he is getting at there. If the client can't position a
popup menu in the correct location it is pretty useless. I suspect he is
using a different definition of "transient" than I am.
Ok. I think I may be understanding transient windows better now (or maybe
have come up with a good definition). I think it's best seen in comparison
to toplevel windows. A toplevel window is "primary" in the sense that you
expect it to have a button in the task bar, want it to show in expose, etc.
A transient window, on the other hand, is one that is peripheral such as a
dialogue box or the floating toolboxes in GIMP. You don't want every
transient window show up in expose mode or in the task bar. In fact, you
don't want it to show up except in relation to another toplevel window.

That said, it is a very different concept to subsurfaces. In particular,
the client should not be able to always know where it is nor should it set
it's location relative to another window directly. (This is different from
popups).

Given this understanding of transient windows, I'm less convinced that we
need a window raise tree. I don't see a reason why the client would want
to raise more than one toplevel window at any given time. It should be
able to just re-parent the needed transient windows and raise the toplevel
one. (or, for that matter, just raise a transient window). The only issue
here is that it needs a way to "commit" the tree so that it can re-arrange
things atomically. If we simply make re-parenting of transient windows not
apply until a raise, we can get atomic.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131023/a4b483eb/attachment-0001.html>
Jonas Ådahl
2013-10-23 21:03:30 UTC
Permalink
Post by Jason Ekstrand
Post by Jason Ekstrand
I see what you mean here. However, I think apps doing this will cause
Post by Jason Ekstrand
more trouble than it's worth. One thing about current sloppy focus
implementations is that you can click anywhere in the window to raise
it. You want to change this. However, what happens if that window is
partially obscured. In your scheme, you would have to move the window
so that the magic text box is uncovered in order to raise it. As is, if
I want to see said text box, I click the window to raise it so I can get
to the text box.
Yes, I agree it would be nice if you could select text without raising
Post by Jason Ekstrand
the window. However, I'd still like a way to raise it without having to
click a particular region. That's an interesting UI problem
I think the clients can raise if the user clicks on a "dead" area where
the click serves no purpose. The most obvious is the window borders, but
also gaps between widgets and widgets that don't use click for anything
could raise the window.
It would still be possible for all the visible area of a surface to be
covered with buttons so there is nowhere to click to raise it. If this is
really a problem then perhaps the user holds down some shift key and clicks?
Perhaps we could allow for some more flexibility if there was a way for
Post by Jason Ekstrand
the client to reject an activation. However, I still have the above fears.
Absolutely a client must be able to "reject an activation". This would be
just like raise and focus: the compositor can only send a request event to
the client. The client must respond with an activate request if it really
wants activation.
However I think this may mean there is no difference between activation
and having a particular seat's keyboard focus.
At this point, I think I can propose a solution which should allow for
1) The xdg_surface has a pare of activate/deactivate events. I think we
need more than keyboard focus here because the user may not have a physical
keyboard.
2) A request_raise event to which the client *can* respond with any number
of raise requests.
3) Both the request_raise and the activate events have a serial. If the
event corresponded to some user input (such as a mouse press) then the
serial will match that of the input event. Otherwise, it will have its own
serial.
4) Inter-surface-commit for making sure the client can raise a
group of windows atomically (?)

Jonas
Post by Jason Ekstrand
Post by Jason Ekstrand
Yes, I like this. I don't think it's feasible to try and keep some
Post by Jason Ekstrand
crazy DAG. As long as a client can atomically raise a bunch of windows
we should be ok. A tree, whether or not it persists after the raise,
will accomplish this.
I think if the tree does not persist then it is identical to the "client
does a lot of raises atomically" version. This is however a possible
solution.
The only reason for the tree is so that other clients can examine it and
get some ideas about the relationship between surfaces. And also for
familiarity with other window systems. I think it may also be useful for
RDP to other window systems which may not have atomic sets of raises.
I believe these child surfaces and "subsurfaces" are
Post by Jason Ekstrand
EXACTLY the
same thing.
I still don't think these *should* be the same. I understand that the
semantics are similar, particularly for popup windows. That said,
Kristian has talked about removing the coordinates from "transient".
Not clear what he is getting at there. If the client can't position a
popup menu in the correct location it is pretty useless. I suspect he is
using a different definition of "transient" than I am.
Ok. I think I may be understanding transient windows better now (or maybe
have come up with a good definition). I think it's best seen in comparison
to toplevel windows. A toplevel window is "primary" in the sense that you
expect it to have a button in the task bar, want it to show in expose, etc.
A transient window, on the other hand, is one that is peripheral such as a
dialogue box or the floating toolboxes in GIMP. You don't want every
transient window show up in expose mode or in the task bar. In fact, you
don't want it to show up except in relation to another toplevel window.
That said, it is a very different concept to subsurfaces. In particular,
the client should not be able to always know where it is nor should it set
it's location relative to another window directly. (This is different from
popups).
Given this understanding of transient windows, I'm less convinced that we
need a window raise tree. I don't see a reason why the client would want
to raise more than one toplevel window at any given time. It should be
able to just re-parent the needed transient windows and raise the toplevel
one. (or, for that matter, just raise a transient window). The only issue
here is that it needs a way to "commit" the tree so that it can re-arrange
things atomically. If we simply make re-parenting of transient windows not
apply until a raise, we can get atomic.
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Bill Spitzak
2013-10-24 02:00:51 UTC
Permalink
Post by Jason Ekstrand
At this point, I think I can propose a solution which should allow for
1) The xdg_surface has a pare of activate/deactivate events. I think
we need more than keyboard focus here because the user may not have a
physical keyboard.
How does a client request an activation? And can it refuse an activation
from the compositor? Here is the sequence I see:

- Compositor sends some kind of "I want you to activate" to client
- Client (if it wants to activate) sends an "activate" request. Clients
can also do this in response to mouse/key events without an activate
from the composiitor.
- Compositor sends a "lost activation" to previous active client, and a
"gained activation" to the new client.

As I see it the only reason the compositor will send the first event is
due to global shortcuts like Alt+Tab or some pager application, and
destruction of the current active client. If clicks or hovering is going
to activate a client, it is the client's responsibility to implement it.

I still feel it is going to be identical to the keyboard focus for some
seat. A seat can have a focus even if it has no keyboard.
Post by Jason Ekstrand
2) A request_raise event to which the client *can* respond with any
number of raise requests.
Again exactly the same sequence. The compositor can send a "I want you
to raise" to the client, which it *can* respond to with raises. The
client can also raise itself in response to events. There probably does
not need to be feedback to the client whether the raise worked.
Post by Jason Ekstrand
3) Both the request_raise and the activate events have a serial. If
the event corresponded to some user input (such as a mouse press) then
the serial will match that of the input event. Otherwise, it will have
its own serial.
Yes. The compositor must be able to tell what event caused the client to
make the request. It can then ignore them, and solve race conditions
with multiple clients.
Post by Jason Ekstrand
Ok. I think I may be understanding transient windows better now (or
maybe have come up with a good definition). I think it's best seen in
comparison to toplevel windows. A toplevel window is "primary" in the
sense that you expect it to have a button in the task bar, want it to
show in expose, etc. A transient window, on the other hand, is one that
is peripheral such as a dialogue box or the floating toolboxes in GIMP.
You don't want every transient window show up in expose mode or in the
task bar. In fact, you don't want it to show up except in relation to
another toplevel window.
That said, it is a very different concept to subsurfaces. In
particular, the client should not be able to always know where it is nor
should it set it's location relative to another window directly. (This
is different from popups).
Having written some applications, I absolutely want complete control
over where transient windows appear!!!! They must appear in correct
positions relative to the mouse cursor and to not obscure important
information in the main window. Also it is very useful to make fancy
transient tooltips that are hovering windows with pointers and that is
not going to work if I can't make the pointers point at things!

If the client tells the compostor to drag a window (due perhaps to a
mouse drag started in the window border) it is probably ok that the
client does not know where the window ends up (though it is really
annoying because it prevents clients from saving their window layouts).

Also I see no reason that the client can't tell the compositor to drag a
subwindow as well. You are not convincing me that there is any
difference, the more I look at it the more I am convinced that these
concepts MUST be merged so that they each don't lack useful abilities
the other ones have.
Post by Jason Ekstrand
Given this understanding of transient windows, I'm less convinced that
we need a window raise tree.
I *think* you are saying "there is no reason for the 'raise tree' to be
a different tree than the 'parent tree'". This is prehaps why I did not
understand what you were getting at. I never wanted more than a single
tree, and I thought Kristian was asking whether there should be *one* or
*zero* trees. Your email was about whether there should be *two* or
*one* tree. I want one, the same as you do, I think.

So what I propose I think is the same as you are proposing: there is a
single tree (actually a forest), of parent/child surface relationships.
The "children" are sometimes called "transient windows", or "popup
windows", etc. This both communicates what window is the "parent" and
makes map and raise of the parents atomic with the children.

If a client really has a reason to make the parenting different than the
raising it can temporarily rearrange the tree before doing a raise and
then put it back.
Rafael Antognolli
2013-10-30 20:19:53 UTC
Permalink
Hi, I'm back to work on this, hopefully this time in a
Post by Bill Spitzak
Post by Jason Ekstrand
At this point, I think I can propose a solution which should allow for
1) The xdg_surface has a pare of activate/deactivate events. I think we
need more than keyboard focus here because the user may not have a physical
keyboard.
How does a client request an activation? And can it refuse an activation
- Compositor sends some kind of "I want you to activate" to client
- Client (if it wants to activate) sends an "activate" request. Clients
can also do this in response to mouse/key events without an activate from
the composiitor.
- Compositor sends a "lost activation" to previous active client, and a
"gained activation" to the new client.
As I see it the only reason the compositor will send the first event is due
to global shortcuts like Alt+Tab or some pager application, and destruction
of the current active client. If clicks or hovering is going to activate a
client, it is the client's responsibility to implement it.
I'm sorry, but I fail to understand how a user could choose between
click to focus, or sloopy focus, if that's up to the client to
implement it. Wouldn't this lead to something like: if I use this
video player A, but it only implements sloopy focus, and I want click
to focus, I have to change to some other video player B?

Again, sorry for my ignorance, I might have not completely understood
your point.
Post by Bill Spitzak
I still feel it is going to be identical to the keyboard focus for some
seat. A seat can have a focus even if it has no keyboard.
Post by Jason Ekstrand
2) A request_raise event to which the client *can* respond with any
number of raise requests.
Again exactly the same sequence. The compositor can send a "I want you to
raise" to the client, which it *can* respond to with raises. The client can
also raise itself in response to events. There probably does not need to be
feedback to the client whether the raise worked.
Post by Jason Ekstrand
3) Both the request_raise and the activate events have a serial. If the
event corresponded to some user input (such as a mouse press) then the
serial will match that of the input event. Otherwise, it will have its own
serial.
Yes. The compositor must be able to tell what event caused the client to
make the request. It can then ignore them, and solve race conditions with
multiple clients.
Post by Jason Ekstrand
Ok. I think I may be understanding transient windows better now (or maybe
have come up with a good definition). I think it's best seen in comparison
to toplevel windows. A toplevel window is "primary" in the sense that you
expect it to have a button in the task bar, want it to show in expose, etc.
A transient window, on the other hand, is one that is peripheral such as a
dialogue box or the floating toolboxes in GIMP. You don't want every
transient window show up in expose mode or in the task bar. In fact, you
don't want it to show up except in relation to another toplevel window.
That said, it is a very different concept to subsurfaces. In particular,
the client should not be able to always know where it is nor should it set
it's location relative to another window directly. (This is different from
popups).
Having written some applications, I absolutely want complete control over
where transient windows appear!!!! They must appear in correct positions
relative to the mouse cursor and to not obscure important information in the
main window. Also it is very useful to make fancy transient tooltips that
are hovering windows with pointers and that is not going to work if I can't
make the pointers point at things!
I agree with you here, we have that exactly same use case in EFL. Not
being able to set where the transient surface will be is going to
prevent us to implement that behavior. Unless some other kind of
surface should be used for this purpose.
Post by Bill Spitzak
If the client tells the compostor to drag a window (due perhaps to a mouse
drag started in the window border) it is probably ok that the client does
not know where the window ends up (though it is really annoying because it
prevents clients from saving their window layouts).
Also I see no reason that the client can't tell the compositor to drag a
subwindow as well. You are not convincing me that there is any difference,
the more I look at it the more I am convinced that these concepts MUST be
merged so that they each don't lack useful abilities the other ones have.
I *think* that the reason behind it is that they have
specific/specialized usage. Subsurfaces are specially for rendering
things not in the main surface, but still merged in the same "window",
so that the user would not see a difference, and have no way to know
that there's another surface in there.

Transient and popup surfaces have another semantic meaning, they are
more like real windows.

For a subsurface, there's no big reason to grab mouse pointer and so.
On the other hand, it wouldn't make sense to synchronize the commit of
a transient window with the one from a toplevel surface. At least from
our toolkit point of view (EFL) it would make things more complicated
IMHO.

Of course they could all be merged, but then we would just end up with
a big generic one surface to rule them all. Not sure if this is
intended.

Though that's only my current understanding, which is quite limited
about Wayland so far.
Post by Bill Spitzak
Post by Jason Ekstrand
Given this understanding of transient windows, I'm less convinced that we
need a window raise tree.
I *think* you are saying "there is no reason for the 'raise tree' to be a
different tree than the 'parent tree'". This is prehaps why I did not
understand what you were getting at. I never wanted more than a single tree,
and I thought Kristian was asking whether there should be *one* or *zero*
trees. Your email was about whether there should be *two* or *one* tree. I
want one, the same as you do, I think.
So what I propose I think is the same as you are proposing: there is a
single tree (actually a forest), of parent/child surface relationships. The
"children" are sometimes called "transient windows", or "popup windows",
etc. This both communicates what window is the "parent" and makes map and
raise of the parents atomic with the children.
If a client really has a reason to make the parenting different than the
raising it can temporarily rearrange the tree before doing a raise and then
put it back.
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
--
Rafael Antognolli
Bill Spitzak
2013-10-31 00:45:39 UTC
Permalink
Post by Rafael Antognolli
I'm sorry, but I fail to understand how a user could choose between
click to focus, or sloopy focus, if that's up to the client to
implement it. Wouldn't this lead to something like: if I use this
video player A, but it only implements sloopy focus, and I want click
to focus, I have to change to some other video player B?
The clients are expected to pay attention to user configuration
settings. This is also how they all use the same fonts and colors, etc.
Post by Rafael Antognolli
For a subsurface, there's no big reason to grab mouse pointer and so.
Actually there is if the subsurface is being managed by a different
client and it wants all the events even if the subsurface was created by
the parent client.
Post by Rafael Antognolli
On the other hand, it wouldn't make sense to synchronize the commit of
a transient window with the one from a toplevel surface. At least from
our toolkit point of view (EFL) it would make things more complicated
IMHO.
It would be useful for making lines connecting the transient windows or
when they are arrows pointing at something in the main window.
Post by Rafael Antognolli
Of course they could all be merged, but then we would just end up with
a big generic one surface to rule them all. Not sure if this is
intended.
That is my intention. I believe this will simplify Wayland considerably
by merging two different implementations of what is actually, as far as
a compositor is concerned, two identical things.
Jason Ekstrand
2013-10-31 02:42:46 UTC
Permalink
Bill,
Because I want to respond to everything in one e-mail, I'm going to try and
address your comments here even though they may not show up.
Post by Rafael Antognolli
Hi, I'm back to work on this, hopefully this time in a
Post by Bill Spitzak
Post by Jason Ekstrand
At this point, I think I can propose a solution which should allow for
1) The xdg_surface has a pare of activate/deactivate events. I think
we
Post by Bill Spitzak
Post by Jason Ekstrand
need more than keyboard focus here because the user may not have a
physical
Post by Bill Spitzak
Post by Jason Ekstrand
keyboard.
How does a client request an activation? And can it refuse an activation
- Compositor sends some kind of "I want you to activate" to client
- Client (if it wants to activate) sends an "activate" request. Clients
can also do this in response to mouse/key events without an activate from
the composiitor.
- Compositor sends a "lost activation" to previous active client, and a
"gained activation" to the new client.
As I see it the only reason the compositor will send the first event is
due
Post by Bill Spitzak
to global shortcuts like Alt+Tab or some pager application, and
destruction
Post by Bill Spitzak
of the current active client. If clicks or hovering is going to activate
a
Post by Bill Spitzak
client, it is the client's responsibility to implement it.
I'm sorry, but I fail to understand how a user could choose between
click to focus, or sloopy focus, if that's up to the client to
implement it. Wouldn't this lead to something like: if I use this
video player A, but it only implements sloopy focus, and I want click
to focus, I have to change to some other video player B?
Again, sorry for my ignorance, I might have not completely understood
your point.
Yes, in theory they could read the configuration of the compositor.
However, that's even more configuration syncing that we have to do and
anything other than the major 3 toolkits (Qt, GTK, and EFL) probably won't
bother. They'll simply implement whatever focus model is easiest (or liked
by the developer) and they certainly won't go searching for special globals
and looking for config files for every compositor/toolkit. I really don't
want to build this kind of inconsistency into the system and I don't see
why it's justified.

Also, why is a client, out of the blue, trying to take the focus? The
compositor is going to have focus rules to prevent bad clients from doing
nasty things anyway. Why not have the compositor tell the client when it's
allowed to have active. This could be as simple as an activate request
with a take_active response. Concerning semantics, I expect the activate
request to be sent whenever an event occurs on a non-active client that the
compositor deems activation-worthy. This could include pointer enter,
pointer button, keyboard key, or nothing client-discernible at all
(alt-tab).

I would expect raise to act the same way (but I don't think we're debating
that one as much.
Post by Rafael Antognolli
Post by Bill Spitzak
I still feel it is going to be identical to the keyboard focus for some
seat. A seat can have a focus even if it has no keyboard.
Post by Jason Ekstrand
2) A request_raise event to which the client *can* respond with any
number of raise requests.
Again exactly the same sequence. The compositor can send a "I want you to
raise" to the client, which it *can* respond to with raises. The client
can
Post by Bill Spitzak
also raise itself in response to events. There probably does not need to
be
Post by Bill Spitzak
feedback to the client whether the raise worked.
I think we agree here. The compositor will have its own rules about when
the client can actually raise. However, it should be able to re-order its
own windows at any time.
Post by Rafael Antognolli
Post by Bill Spitzak
Post by Jason Ekstrand
3) Both the request_raise and the activate events have a serial. If
the
Post by Bill Spitzak
Post by Jason Ekstrand
event corresponded to some user input (such as a mouse press) then the
serial will match that of the input event. Otherwise, it will have its
own
Post by Bill Spitzak
Post by Jason Ekstrand
serial.
Yes. The compositor must be able to tell what event caused the client to
make the request. It can then ignore them, and solve race conditions with
multiple clients.
Post by Jason Ekstrand
Ok. I think I may be understanding transient windows better now (or
maybe
Post by Bill Spitzak
Post by Jason Ekstrand
have come up with a good definition). I think it's best seen in
comparison
Post by Bill Spitzak
Post by Jason Ekstrand
to toplevel windows. A toplevel window is "primary" in the sense that
you
Post by Bill Spitzak
Post by Jason Ekstrand
expect it to have a button in the task bar, want it to show in expose,
etc.
Post by Bill Spitzak
Post by Jason Ekstrand
A transient window, on the other hand, is one that is peripheral such
as a
Post by Bill Spitzak
Post by Jason Ekstrand
dialogue box or the floating toolboxes in GIMP. You don't want every
transient window show up in expose mode or in the task bar. In fact,
you
Post by Bill Spitzak
Post by Jason Ekstrand
don't want it to show up except in relation to another toplevel window.
That said, it is a very different concept to subsurfaces. In
particular,
Post by Bill Spitzak
Post by Jason Ekstrand
the client should not be able to always know where it is nor should it
set
Post by Bill Spitzak
Post by Jason Ekstrand
it's location relative to another window directly. (This is different
from
Post by Bill Spitzak
Post by Jason Ekstrand
popups).
Having written some applications, I absolutely want complete control over
where transient windows appear!!!! They must appear in correct positions
relative to the mouse cursor and to not obscure important information in
the
Post by Bill Spitzak
main window. Also it is very useful to make fancy transient tooltips that
are hovering windows with pointers and that is not going to work if I
can't
Post by Bill Spitzak
make the pointers point at things!
I agree with you here, we have that exactly same use case in EFL. Not
being able to set where the transient surface will be is going to
prevent us to implement that behavior. Unless some other kind of
surface should be used for this purpose.
One thing worth noting here is that the client doesn't know where the
window is, so it can't always properly place these transient windows (in
the case of toolboxes). I know, Bill, that you have advocated many times
in the past that the compositor give the client the full transformation
matrix of the window at all times. However I don't think this is going to
happen. It wasn't my decision. Let's not start that argument again here.
If we want to restore window positions (and I would like that eventually),
I think we can come up with some way of doing so that doesn't make the
compositor slave to the clients.

Now, concerning other pop-up type things such as tooltips, speech bubbles,
arrows, etc. Perhaps they aren't the same as a standard transient window.
I would want a toolbox to not show up in a task bar (not toplevel) but to
also move independent of its parent. Perhaps there is another category in
here. Maybe we want four types: toplevel, transient (toolboxes etc.),
tooltip (position relative to parent), and popup (tooltip + grab
semantics). It would be good to talk to Giulio Camuffo about this as he
spent quite some time banging his head on menus in Qt.
Post by Rafael Antognolli
Post by Bill Spitzak
If the client tells the compostor to drag a window (due perhaps to a
mouse
Post by Bill Spitzak
drag started in the window border) it is probably ok that the client does
not know where the window ends up (though it is really annoying because
it
Post by Bill Spitzak
prevents clients from saving their window layouts).
Also I see no reason that the client can't tell the compositor to drag a
subwindow as well. You are not convincing me that there is any
difference,
Post by Bill Spitzak
the more I look at it the more I am convinced that these concepts MUST be
merged so that they each don't lack useful abilities the other ones have.
I *think* that the reason behind it is that they have
specific/specialized usage. Subsurfaces are specially for rendering
things not in the main surface, but still merged in the same "window",
so that the user would not see a difference, and have no way to know
that there's another surface in there.
Yes! In particular, subsurfaces are a compositor-wide thing, where as
popup/transient/tooltip is entirely a *shell* thing. Perhaps in some
compositor there is no distinction. However, just because they look
similar in the scenegraph does not mean they are the same.
Post by Rafael Antognolli
Transient and popup surfaces have another semantic meaning, they are
more like real windows.
Yes, they are real windows. This also tells the compositor that the
surface is not actually part of the window. For instance, it may not want
to render menus/tooltips in an expose mode. However, subsurfaces would
have to get rendered in that mode because they are part of the original
surface.
Post by Rafael Antognolli
For a subsurface, there's no big reason to grab mouse pointer and so.
On the other hand, it wouldn't make sense to synchronize the commit of
a transient window with the one from a toplevel surface. At least from
our toolkit point of view (EFL) it would make things more complicated
IMHO.
Of course they could all be merged, but then we would just end up with
a big generic one surface to rule them all. Not sure if this is
intended.
I really don't think we want one surface to rule them all. There is also a
huge component-separation issue here. I don't want subsurfaces to be 100%
a shell thing and I don't want grab symantics built into subsurfaces (or
window move symantics for that matter). If we couple things too closely,
it's going to make it impossible to implement anything other than a desktop
shell with Wayland. We DO NOT want that!
Post by Rafael Antognolli
Though that's only my current understanding, which is quite limited
about Wayland so far.
Post by Bill Spitzak
Post by Jason Ekstrand
Given this understanding of transient windows, I'm less convinced that
we
Post by Bill Spitzak
Post by Jason Ekstrand
need a window raise tree.
I *think* you are saying "there is no reason for the 'raise tree' to be a
different tree than the 'parent tree'". This is prehaps why I did not
understand what you were getting at. I never wanted more than a single
tree,
Post by Bill Spitzak
and I thought Kristian was asking whether there should be *one* or *zero*
trees. Your email was about whether there should be *two* or *one* tree.
I
Post by Bill Spitzak
want one, the same as you do, I think.
So what I propose I think is the same as you are proposing: there is a
single tree (actually a forest), of parent/child surface relationships.
The
Post by Bill Spitzak
"children" are sometimes called "transient windows", or "popup windows",
etc. This both communicates what window is the "parent" and makes map and
raise of the parents atomic with the children.
If a client really has a reason to make the parenting different than the
raising it can temporarily rearrange the tree before doing a raise and
then
Post by Bill Spitzak
put it back.
I'm pretty sure we agree here. I see no reason for 2 trees either. And I
do think we want some sort of a tree. I think it's reasonable to make the
toplevel windows roots (no parent) and make all the other little window
types (popup, transient, tooltip) take a parent parameter which does not
have to be toplevel. However, I would also like there to be some sort of
"commit" operation so it can be don atomically. One idea would be to
simply make that commit operation the same as the raise.

Thanks, I hope I addressed everything.
--Jason Ekstrand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131030/94022501/attachment.html>
Rafael Antognolli
2013-10-31 13:36:56 UTC
Permalink
Post by Jason Ekstrand
Bill,
Because I want to respond to everything in one e-mail, I'm going to try and
address your comments here even though they may not show up.
On Wed, Oct 30, 2013 at 3:19 PM, Rafael Antognolli <antognolli at gmail.com>
Post by Rafael Antognolli
Hi, I'm back to work on this, hopefully this time in a
Post by Bill Spitzak
Post by Jason Ekstrand
At this point, I think I can propose a solution which should allow for
1) The xdg_surface has a pare of activate/deactivate events. I think we
need more than keyboard focus here because the user may not have a physical
keyboard.
How does a client request an activation? And can it refuse an activation
- Compositor sends some kind of "I want you to activate" to client
- Client (if it wants to activate) sends an "activate" request. Clients
can also do this in response to mouse/key events without an activate from
the composiitor.
- Compositor sends a "lost activation" to previous active client, and a
"gained activation" to the new client.
As I see it the only reason the compositor will send the first event is due
to global shortcuts like Alt+Tab or some pager application, and destruction
of the current active client. If clicks or hovering is going to activate a
client, it is the client's responsibility to implement it.
I'm sorry, but I fail to understand how a user could choose between
click to focus, or sloopy focus, if that's up to the client to
implement it. Wouldn't this lead to something like: if I use this
video player A, but it only implements sloopy focus, and I want click
to focus, I have to change to some other video player B?
Again, sorry for my ignorance, I might have not completely understood
your point.
Yes, in theory they could read the configuration of the compositor.
However, that's even more configuration syncing that we have to do and
anything other than the major 3 toolkits (Qt, GTK, and EFL) probably won't
bother. They'll simply implement whatever focus model is easiest (or liked
by the developer) and they certainly won't go searching for special globals
and looking for config files for every compositor/toolkit. I really don't
want to build this kind of inconsistency into the system and I don't see why
it's justified.
Yes, either implementing the easiest, or the one that they think it
makes more sense. Or, if they do want to read configuration and
implement everything correctly, it will be a lot complexity.

On the other hand, the compositor having the logic of when it should
focus a window, and sending such event to the client, simplify things
in the client. But that does not prevent the client to request focus
at any time, when a mouse movement is detected, or some other kind of
event. Which kind of gives flexibility to the client to implement any
special behavior.
Post by Jason Ekstrand
Also, why is a client, out of the blue, trying to take the focus? The
compositor is going to have focus rules to prevent bad clients from doing
nasty things anyway. Why not have the compositor tell the client when it's
allowed to have active. This could be as simple as an activate request with
a take_active response. Concerning semantics, I expect the activate request
to be sent whenever an event occurs on a non-active client that the
compositor deems activation-worthy. This could include pointer enter,
pointer button, keyboard key, or nothing client-discernible at all
(alt-tab).
OK, I wasn't thinking about anything to allow/prevent a client to take
focus, but that can be done too. Do you think we can go with a simpler
approach (not preventing anything), and add that later, just to
finally start things and have something working soon?
Post by Jason Ekstrand
I would expect raise to act the same way (but I don't think we're debating
that one as much.
Post by Rafael Antognolli
Post by Bill Spitzak
I still feel it is going to be identical to the keyboard focus for some
seat. A seat can have a focus even if it has no keyboard.
Post by Jason Ekstrand
2) A request_raise event to which the client *can* respond with any
number of raise requests.
Again exactly the same sequence. The compositor can send a "I want you to
raise" to the client, which it *can* respond to with raises. The client can
also raise itself in response to events. There probably does not need to be
feedback to the client whether the raise worked.
I think we agree here. The compositor will have its own rules about when
the client can actually raise. However, it should be able to re-order its
own windows at any time.
This looks good to me.
Post by Jason Ekstrand
Post by Rafael Antognolli
Post by Bill Spitzak
Post by Jason Ekstrand
3) Both the request_raise and the activate events have a serial. If the
event corresponded to some user input (such as a mouse press) then the
serial will match that of the input event. Otherwise, it will have its own
serial.
Yes. The compositor must be able to tell what event caused the client to
make the request. It can then ignore them, and solve race conditions with
multiple clients.
Post by Jason Ekstrand
Ok. I think I may be understanding transient windows better now (or maybe
have come up with a good definition). I think it's best seen in comparison
to toplevel windows. A toplevel window is "primary" in the sense that you
expect it to have a button in the task bar, want it to show in expose, etc.
A transient window, on the other hand, is one that is peripheral such as a
dialogue box or the floating toolboxes in GIMP. You don't want every
transient window show up in expose mode or in the task bar. In fact, you
don't want it to show up except in relation to another toplevel window.
That said, it is a very different concept to subsurfaces. In particular,
the client should not be able to always know where it is nor should it set
it's location relative to another window directly. (This is different from
popups).
Having written some applications, I absolutely want complete control over
where transient windows appear!!!! They must appear in correct positions
relative to the mouse cursor and to not obscure important information in the
main window. Also it is very useful to make fancy transient tooltips that
are hovering windows with pointers and that is not going to work if I can't
make the pointers point at things!
I agree with you here, we have that exactly same use case in EFL. Not
being able to set where the transient surface will be is going to
prevent us to implement that behavior. Unless some other kind of
surface should be used for this purpose.
One thing worth noting here is that the client doesn't know where the window
is, so it can't always properly place these transient windows (in the case
of toolboxes). I know, Bill, that you have advocated many times in the past
that the compositor give the client the full transformation matrix of the
window at all times. However I don't think this is going to happen. It
wasn't my decision. Let's not start that argument again here. If we want
to restore window positions (and I would like that eventually), I think we
can come up with some way of doing so that doesn't make the compositor slave
to the clients.
I don't agree with this, but fine, let's do the simplest first.

So, what about this: I add only the expected surface types (toplevel,
transient, popup), transient should have no way to set its position.
Later, if we find it necessary, we can either add a new type, or add
an API to set transient's position? It would at least postpone this
discussion, or maybe we even move it to another thread, specific to
this topic.
Post by Jason Ekstrand
Now, concerning other pop-up type things such as tooltips, speech bubbles,
arrows, etc. Perhaps they aren't the same as a standard transient window.
I would want a toolbox to not show up in a task bar (not toplevel) but to
also move independent of its parent. Perhaps there is another category in
here. Maybe we want four types: toplevel, transient (toolboxes etc.),
tooltip (position relative to parent), and popup (tooltip + grab semantics).
It would be good to talk to Giulio Camuffo about this as he spent quite some
time banging his head on menus in Qt.
Post by Rafael Antognolli
Post by Bill Spitzak
If the client tells the compostor to drag a window (due perhaps to a mouse
drag started in the window border) it is probably ok that the client does
not know where the window ends up (though it is really annoying because it
prevents clients from saving their window layouts).
Also I see no reason that the client can't tell the compositor to drag a
subwindow as well. You are not convincing me that there is any difference,
the more I look at it the more I am convinced that these concepts MUST be
merged so that they each don't lack useful abilities the other ones have.
I *think* that the reason behind it is that they have
specific/specialized usage. Subsurfaces are specially for rendering
things not in the main surface, but still merged in the same "window",
so that the user would not see a difference, and have no way to know
that there's another surface in there.
Yes! In particular, subsurfaces are a compositor-wide thing, where as
popup/transient/tooltip is entirely a *shell* thing. Perhaps in some
compositor there is no distinction. However, just because they look similar
in the scenegraph does not mean they are the same.
Post by Rafael Antognolli
Transient and popup surfaces have another semantic meaning, they are
more like real windows.
Yes, they are real windows. This also tells the compositor that the surface
is not actually part of the window. For instance, it may not want to render
menus/tooltips in an expose mode. However, subsurfaces would have to get
rendered in that mode because they are part of the original surface.
Post by Rafael Antognolli
For a subsurface, there's no big reason to grab mouse pointer and so.
On the other hand, it wouldn't make sense to synchronize the commit of
a transient window with the one from a toplevel surface. At least from
our toolkit point of view (EFL) it would make things more complicated
IMHO.
Of course they could all be merged, but then we would just end up with
a big generic one surface to rule them all. Not sure if this is
intended.
I really don't think we want one surface to rule them all. There is also a
huge component-separation issue here. I don't want subsurfaces to be 100% a
shell thing and I don't want grab symantics built into subsurfaces (or
window move symantics for that matter). If we couple things too closely,
it's going to make it impossible to implement anything other than a desktop
shell with Wayland. We DO NOT want that!
Post by Rafael Antognolli
Though that's only my current understanding, which is quite limited
about Wayland so far.
Post by Bill Spitzak
Post by Jason Ekstrand
Given this understanding of transient windows, I'm less convinced that we
need a window raise tree.
I *think* you are saying "there is no reason for the 'raise tree' to be a
different tree than the 'parent tree'". This is prehaps why I did not
understand what you were getting at. I never wanted more than a single tree,
and I thought Kristian was asking whether there should be *one* or *zero*
trees. Your email was about whether there should be *two* or *one* tree. I
want one, the same as you do, I think.
So what I propose I think is the same as you are proposing: there is a
single tree (actually a forest), of parent/child surface relationships. The
"children" are sometimes called "transient windows", or "popup windows",
etc. This both communicates what window is the "parent" and makes map and
raise of the parents atomic with the children.
If a client really has a reason to make the parenting different than the
raising it can temporarily rearrange the tree before doing a raise and then
put it back.
I'm pretty sure we agree here. I see no reason for 2 trees either. And I
do think we want some sort of a tree. I think it's reasonable to make the
toplevel windows roots (no parent) and make all the other little window
types (popup, transient, tooltip) take a parent parameter which does not
have to be toplevel. However, I would also like there to be some sort of
"commit" operation so it can be don atomically. One idea would be to
simply make that commit operation the same as the raise.
That makes sense to me.
Post by Jason Ekstrand
Thanks, I hope I addressed everything.
I'll try to come up with a protocol spec for that, and we can keep
working on fine tuning it if you agree.
--
Rafael Antognolli
Bill Spitzak
2013-10-31 20:37:25 UTC
Permalink
Post by Jason Ekstrand
Yes, in theory they could read the configuration of the compositor.
I really don't want to build this kind of
inconsistency into the system and I don't see why it's justified.
I think I see what you are getting at. I think a scheme that allows
simple applications to obey the global setting without thinking, but
still allows applications that have a good reason to do tricks with the
focus, and also matches the raise proposal, is this:

- The compositor sends an "I want you to activate" event, as you propose.
- The client can respond to this with an "activate" request. Or it could
send an "activate" request at other times if it wants.
- The compositor responds to the "activate" request by either ignoring
it or actually doing the activation.
- The compositor sends an "activated" event that the client can respond
to by redrawing to show the fact that they are activated.

If a client just echoes the "I want you to activate" event then it will
work as you expect. A client could also wait after the event until the
mouse enters a correct location or clicks on the right thing. It could
also try to generate spurious activates but the compositor may ignore them.
Post by Jason Ekstrand
I agree with you here, we have that exactly same use case in EFL. Not
being able to set where the transient surface will be is going to
prevent us to implement that behavior. Unless some other kind of
surface should be used for this purpose.
One thing worth noting here is that the client doesn't know where the
window is, so it can't always properly place these transient windows (in
the case of toolboxes).
The location of transient windows is *relative* to the parent's
transform, not absolute.

There are already proposed and implemented apis to discover if a
rectangle in the parent's space is clipped by output edges and panels,
so a client can choose a different rectangle.
Post by Jason Ekstrand
I know, Bill, that you have advocated many
times in the past that the compositor give the client the full
transformation matrix of the window at all times. However I don't think
this is going to happen. It wasn't my decision.
Yea I give up on this as well, and relative transforms of transient
windows avoids this problem for now.
Post by Jason Ekstrand
Now, concerning other pop-up type things such as tooltips, speech
bubbles, arrows, etc. Perhaps they aren't the same as a standard
transient window. I would want a toolbox to not show up in a task bar
(not toplevel) but to also move independent of its parent. Perhaps
there is another category in here. Maybe we want four types: toplevel,
transient (toolboxes etc.), tooltip (position relative to parent), and
popup (tooltip + grab semantics). It would be good to talk to Giulio
Camuffo about this as he spent quite some time banging his head on menus
in Qt.
I think this will have to be a bunch of flags or you will end up with
2^N different window types. Flags I can see:

- Locked transform (whether the window moves when the parent does)
- Show in task bar (I'm not convinced this is ever wanted)
- Show in thumbnail (may be same as locked transform?)
- Whether it is a subsurface, or a window, or a window above the panels.
- Clipped to parent (this has been requested a bunch and may be
necessary if client cannot absolutely control the location).
- Grab

The current grab I don't like. It seems that the surface is always
unmapped on a click outside it. Also there is an entire somewhat
parallel grab mechanism for normal surfaces. I am pretty certain this
can and should all be merged. A popup transient would be a normal
transient except the client also grabs the pointer. Losing the grab
would work like Windows (if press + release are both outside the grab
surface then the grab is cancelled after the release is delivered to the
client).
Post by Jason Ekstrand
I do think we want some sort of a tree. I think it's reasonable to make
the toplevel windows roots (no parent) and make all the other little
window types (popup, transient, tooltip) take a parent parameter which
does not have to be toplevel.
This sounds identical to what I want.
Post by Jason Ekstrand
However, I would also like there to be
some sort of "commit" operation so it can be don atomically. One idea
would be to simply make that commit operation the same as the raise.
As I see it, the client can change the tree all they want with no
visible effect (even though the current stacking may be "wrong"). The
only thing the tree does is that when a raise happens, it also
atomically raises all child surfaces along with it. Thus the raise acts
as the "commit".
Jason Ekstrand
2013-11-01 01:28:58 UTC
Permalink
Post by Jason Ekstrand
Yes, in theory they could read the configuration of the compositor.
I really don't want to build this kind of inconsistency into the system
Post by Jason Ekstrand
and I don't see why it's justified.
I think I see what you are getting at. I think a scheme that allows simple
applications to obey the global setting without thinking, but still allows
applications that have a good reason to do tricks with the focus, and also
- The compositor sends an "I want you to activate" event, as you propose.
- The client can respond to this with an "activate" request. Or it could
send an "activate" request at other times if it wants.
- The compositor responds to the "activate" request by either ignoring it
or actually doing the activation.
- The compositor sends an "activated" event that the client can respond to
by redrawing to show the fact that they are activated.
If a client just echoes the "I want you to activate" event then it will
work as you expect. A client could also wait after the event until the
mouse enters a correct location or clicks on the right thing. It could also
try to generate spurious activates but the compositor may ignore them.
I still don't understand why a client would want to not activate. I can
see not wanting to raise, but why not activate?
Post by Jason Ekstrand
I agree with you here, we have that exactly same use case in EFL. Not
Post by Jason Ekstrand
being able to set where the transient surface will be is going to
prevent us to implement that behavior. Unless some other kind of
surface should be used for this purpose.
One thing worth noting here is that the client doesn't know where the
window is, so it can't always properly place these transient windows (in
the case of toolboxes).
The location of transient windows is *relative* to the parent's transform,
not absolute.
There are already proposed and implemented apis to discover if a rectangle
in the parent's space is clipped by output edges and panels, so a client
can choose a different rectangle.
See below for an idea on how to make this happen.
Post by Jason Ekstrand
I know, Bill, that you have advocated many times in the past that the
Post by Jason Ekstrand
compositor give the client the full transformation matrix of the window at
all times. However I don't think this is going to happen. It wasn't my
decision.
Yea I give up on this as well, and relative transforms of transient
windows avoids this problem for now.
Now, concerning other pop-up type things such as tooltips, speech
Post by Jason Ekstrand
bubbles, arrows, etc. Perhaps they aren't the same as a standard transient
window. I would want a toolbox to not show up in a task bar (not toplevel)
but to also move independent of its parent. Perhaps there is another
category in here. Maybe we want four types: toplevel, transient (toolboxes
etc.), tooltip (position relative to parent), and popup (tooltip + grab
semantics). It would be good to talk to Giulio Camuffo about this as he
spent quite some time banging his head on menus in Qt.
I think this will have to be a bunch of flags or you will end up with 2^N
- Locked transform (whether the window moves when the parent does)
- Show in task bar (I'm not convinced this is ever wanted)
Why not? Maybe we're missing each other on this one. By "show in task
bar" I don't mean as a tray icon. I mean that it's toplevel and it shows
up as an independently user-activateble window. In windows, this means it
has a button in the task bar. In gnome shell, it shows up in the list of
windows when you right-click a dock icon. In KDE it shows up in whatever
they call their task bar. However, I think this is covered by toplevel
(which I think we should keep.)
Post by Jason Ekstrand
- Show in thumbnail (may be same as locked transform?)
- Whether it is a subsurface, or a window, or a window above the panels.
- Clipped to parent (this has been requested a bunch and may be necessary
if client cannot absolutely control the location).
- Grab
You raise a good point here. There is a real possibility that we will end
up with too many different window types. It does seem somewhat reasonable
to have "toplevel" and "transient" and let grab symantics, parent position
locking, etc. be flags. We already have a bunch of flags for toplevel
windows such as maximize/fullscreen, etc.

*if* we decide to go with flags, I would recommend a set_relative_position
request and an unset_relative_position. Attaching a buffer with a non-zero
x and y would change the position but otherwise leave the lock intact. The
xdg_shell.move request or anything similar would automatically release the
lock. Does this seem reasonable? Another option would be to just set it
at (0, 0) relative to the parent and use the next buffer attach to
determine the position.

All this being said, I don't think it's a stopper. As I discussed with
Rafael on IRC, as long as we remove the position arguments from
set_transient, we can always add these flags later. So I don't think this
needs to get solved before he starts implementing.
Post by Jason Ekstrand
The current grab I don't like. It seems that the surface is always
unmapped on a click outside it. Also there is an entire somewhat parallel
grab mechanism for normal surfaces. I am pretty certain this can and should
all be merged. A popup transient would be a normal transient except the
client also grabs the pointer. Losing the grab would work like Windows (if
press + release are both outside the grab surface then the grab is
cancelled after the release is delivered to the client).
I'm not 100% familiar with all the issues here. I'll look into it more.
Post by Jason Ekstrand
I do think we want some sort of a tree. I think it's reasonable to make
Post by Jason Ekstrand
the toplevel windows roots (no parent) and make all the other little window
types (popup, transient, tooltip) take a parent parameter which does not
have to be toplevel.
This sounds identical to what I want.
However, I would also like there to be some sort of "commit" operation
Post by Jason Ekstrand
so it can be don atomically. One idea would be to simply make that commit
operation the same as the raise.
As I see it, the client can change the tree all they want with no visible
effect (even though the current stacking may be "wrong"). The only thing
the tree does is that when a raise happens, it also atomically raises all
child surfaces along with it. Thus the raise acts as the "commit".
Yup, I think we agree on both of the above two.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131031/db9b75b9/attachment-0001.html>
Bill Spitzak
2013-11-01 18:42:09 UTC
Permalink
Post by Jason Ekstrand
I still don't understand why a client would want to not activate. I can
see not wanting to raise, but why not activate?
The main one I see is you do not want attempts to drag an object to
activate the drag-from client, since this may unmap the desired target
of the drag since it belongs to the former active client. Dropping would
activate the dropped-on client.

I also feel like point-to-type could be helped by this, though I am
unsure how. The main reason is that "sloppy focus" could be considered
the desktop refusing to take focus when the cursor enters it.
Post by Jason Ekstrand
- Show in task bar (I'm not convinced this is ever wanted)
Why not? Maybe we're missing each other on this one. By "show in task
bar" I don't mean as a tray icon. I mean that it's toplevel and it
shows up as an independently user-activateble window.
What I meant was I don't know if it is ever wanted for non-toplevel
surfaces to show in the taskbar. Thus the flag may not be needed since
whether or not the surface has a parent controls this.

If there is a desire for top-level surfaces that are not in the taskbar
then a flag will be needed. If transient windows should be in the
taskbar then the client could just do the raises itself, but it may be
useful to have the flag then as well.
Post by Jason Ekstrand
*if* we decide to go with flags, I would recommend a
set_relative_position request and an unset_relative_position. Attaching
a buffer with a non-zero x and y would change the position but otherwise
leave the lock intact. The xdg_shell.move request or anything similar
would automatically release the lock. Does this seem reasonable?
Another option would be to just set it at (0, 0) relative to the parent
and use the next buffer attach to determine the position.
Actually that (the 0,0 idea) sounds like a very good idea and in keeping
with the design of the rest of Wayland.

There will probably need to be scaling and other affine transforms as
well, but these are needed for subsurfaces and top-level surfaces. In
any case it would be cleaner if transforms were different requests
rather than having to put the entire transform on the map call.
Gregory Merchan
2013-11-02 01:36:04 UTC
Permalink
Post by Jason Ekstrand
Post by Jason Ekstrand
Yes, in theory they could read the configuration of the compositor.
I really don't want to build this kind of inconsistency into the system
and I don't see why it's justified.
I think I see what you are getting at. I think a scheme that allows simple
applications to obey the global setting without thinking, but still allows
applications that have a good reason to do tricks with the focus, and also
- The compositor sends an "I want you to activate" event, as you propose.
- The client can respond to this with an "activate" request. Or it could
send an "activate" request at other times if it wants.
- The compositor responds to the "activate" request by either ignoring it
or actually doing the activation.
- The compositor sends an "activated" event that the client can respond to
by redrawing to show the fact that they are activated.
If a client just echoes the "I want you to activate" event then it will
work as you expect. A client could also wait after the event until the mouse
enters a correct location or clicks on the right thing. It could also try to
generate spurious activates but the compositor may ignore them.
I still don't understand why a client would want to not activate. I can see
not wanting to raise, but why not activate?
As Bill mentioned in a follow-up, drag sources would want to not activate.

This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.

First, clients are responsible for requesting activation when it is appropriate.
Second, the compositor always activates when it is appropriate.

The complicated part is determining what is appropriate.

There are 5 activation policies. For each policy, the compositor
activates windows as needed for key traversal (e.g. Alt+Tab), task bar
actions, when an active window goes away, viewport changes, etc. The
compositor also activates windows when a request for activation has
the correct signature. The policies are distinguished by special cases
for activation or deactivation:

1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
2. Sloppy: Activates a window when the pointer enters it.
3. Delayed sloppy: Activates a window when the pointer has been within
for a short time.
4. Click-to-focus: Activates a window when it is clicked.
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.

(I suppose a "Delayed PointerRoot" policy is possible, but I've never
seen any discussion of it.)

For each of these policies, another distinction may be made according
to signature required to honor an activation request. The strictest
form is to deny all requests, which is not possible on X11 because
there is no redirection for focus changes. An often desired form for
the correct signature, among X11 users, is that the request must come
from a client which is already activated. For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows. Unless I am mistaken, most attempts at "focus
stealing prevention" have aimed at such a policy. I'm pretty sure I've
seen at least one window manager that will fight with bad programs to
enforce such a policy. On X11, the correct signature is always only
that the timestamp is later than the last focus change timestamp, and
this may be achieved by using CURRENT_TIME. Convention is relied upon
to avoid chaos, that convention is that clients must always use a
valid timestamp to set focus, and there are 4 sources of valid
timestamps: 1) button events, 2) key events, 3) property change
events, and 4) a window manager message. This last source exists to
address the lack of a timestamp in the focus change event of the X
protocol. I will refer to this as the "valid event" signature.

Wayland is a different system and there are more options for the
signature requirement. If I understand the protocol correctly, the
serial field of pointer, keyboard, and touch events could be used as a
signature. (Like X, wl_keyboard::enter does not have a time argument,
so that is not an option.) The strictest form of these
policies--denying all requests--can be achieved because the compositor
is in control; it's like a window manager and an X server combined in
that sense. The "must be active" signature can be implemented by
checking that the serial number came from an event sent to an active
client. The valid event signature can be implemented by checking that
the serial number came from a wl_pointer::button event, a
wl_keyboard::key event, a wl_keyboard::enter event, or wl_touch::down
event.

The compositor is always in control, so clients can request activation
as much as they like without messing things up. Clients cannot prevent
the compositor from implementing any of the five activation policies.
The first four policies require nothing from clients to work as
expected; they are what we've had on X forever. The last policy does
not work unless clients request activation as needed when they have a
valid event. To my knowledge, both Windows and MacOS already require
applications to request activation in this way, so cross-platform
toolkits don't have to make a special case. This is the first
requirement that was stated before: clients are responsible for
requesting activation when it is appropriate.

I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window. Make
that distinction and the problem is solved; choose whichever stacking
policy you would like. If the distinction between the frame and the
rest of the window is included in the request for activation, you can
even have clicks in the client raise, but only clicks on the frame
activate, though I can think of no reason beyond sadism why anyone
would make things work that way.

I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus. I
believe it would be sensible to keep the active window on top within
its bounds, excepting for secondary windows, like tool palettes, which
should stay above the primary window. This is the stacking behavior
familiar to users of Windows and MacOS. I emphasize that the stacking
policy is independent of the activation policy, so long as the
compositor can distinguish between frames and their contents.

The guides I gave before--clients request activation responsibly,
compositors activate appropriately--allow all users to use their
chosen compositors with any application targeted at Wayland.

The combination of Windows/MacOS-style activation policy with an
active-window-on-top stacking policy is the behavior familiar to
Windows and MacOS users, including the allowance for beginning a
drag-and-drop operation without raising the drag source window. Much
the same system is possible on X11 if window managers will not grab
buttons without modifiers and regular clients will use the globally
active input model, requesting input focus when appropriate. Perhaps
most important to many reading this list is that the all the
activation policies familiar from X are compatible with the client
behavior I have described.

When I'm done with my current project at work, I'll be able to see
about writing code for what I have described, but that's weeks or
months away and then I'll need time to reacquaint myself with pretty
much everything. I hope that this has been a useful message. I
apologize for the lengthy lack of code.
Jason Ekstrand
2013-11-02 03:58:58 UTC
Permalink
On Fri, Nov 1, 2013 at 8:36 PM, Gregory Merchan
Post by antognolli
Post by Jason Ekstrand
Post by Bill Spitzak
Post by Jason Ekstrand
Yes, in theory they could read the configuration of the compositor.
I really don't want to build this kind of inconsistency into the system
and I don't see why it's justified.
I think I see what you are getting at. I think a scheme that allows
simple
Post by Jason Ekstrand
Post by Bill Spitzak
applications to obey the global setting without thinking, but still
allows
Post by Jason Ekstrand
Post by Bill Spitzak
applications that have a good reason to do tricks with the focus, and
also
Post by Jason Ekstrand
Post by Bill Spitzak
- The compositor sends an "I want you to activate" event, as you
propose.
Post by Jason Ekstrand
Post by Bill Spitzak
- The client can respond to this with an "activate" request. Or it could
send an "activate" request at other times if it wants.
- The compositor responds to the "activate" request by either ignoring
it
Post by Jason Ekstrand
Post by Bill Spitzak
or actually doing the activation.
- The compositor sends an "activated" event that the client can respond
to
Post by Jason Ekstrand
Post by Bill Spitzak
by redrawing to show the fact that they are activated.
If a client just echoes the "I want you to activate" event then it will
work as you expect. A client could also wait after the event until the
mouse
Post by Jason Ekstrand
Post by Bill Spitzak
enters a correct location or clicks on the right thing. It could also
try to
Post by Jason Ekstrand
Post by Bill Spitzak
generate spurious activates but the compositor may ignore them.
I still don't understand why a client would want to not activate. I can
see
Post by Jason Ekstrand
not wanting to raise, but why not activate?
As Bill mentioned in a follow-up, drag sources would want to not activate.
This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.
First, clients are responsible for requesting activation when it is appropriate.
Second, the compositor always activates when it is appropriate.
The complicated part is determining what is appropriate.
There are 5 activation policies. For each policy, the compositor
activates windows as needed for key traversal (e.g. Alt+Tab), task bar
actions, when an active window goes away, viewport changes, etc. The
compositor also activates windows when a request for activation has
the correct signature. The policies are distinguished by special cases
1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
2. Sloppy: Activates a window when the pointer enters it.
3. Delayed sloppy: Activates a window when the pointer has been within
for a short time.
4. Click-to-focus: Activates a window when it is clicked.
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.
(I suppose a "Delayed PointerRoot" policy is possible, but I've never
seen any discussion of it.)
For each of these policies, another distinction may be made according
to signature required to honor an activation request. The strictest
form is to deny all requests, which is not possible on X11 because
there is no redirection for focus changes. An often desired form for
the correct signature, among X11 users, is that the request must come
from a client which is already activated. For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows. Unless I am mistaken, most attempts at "focus
stealing prevention" have aimed at such a policy. I'm pretty sure I've
seen at least one window manager that will fight with bad programs to
enforce such a policy. On X11, the correct signature is always only
that the timestamp is later than the last focus change timestamp, and
this may be achieved by using CURRENT_TIME. Convention is relied upon
to avoid chaos, that convention is that clients must always use a
valid timestamp to set focus, and there are 4 sources of valid
timestamps: 1) button events, 2) key events, 3) property change
events, and 4) a window manager message. This last source exists to
address the lack of a timestamp in the focus change event of the X
protocol. I will refer to this as the "valid event" signature.
Wayland is a different system and there are more options for the
signature requirement. If I understand the protocol correctly, the
serial field of pointer, keyboard, and touch events could be used as a
signature. (Like X, wl_keyboard::enter does not have a time argument,
so that is not an option.) The strictest form of these
policies--denying all requests--can be achieved because the compositor
is in control; it's like a window manager and an X server combined in
that sense. The "must be active" signature can be implemented by
checking that the serial number came from an event sent to an active
client. The valid event signature can be implemented by checking that
the serial number came from a wl_pointer::button event, a
wl_keyboard::key event, a wl_keyboard::enter event, or wl_touch::down
event.
The compositor is always in control, so clients can request activation
as much as they like without messing things up. Clients cannot prevent
the compositor from implementing any of the five activation policies.
The first four policies require nothing from clients to work as
expected; they are what we've had on X forever. The last policy does
not work unless clients request activation as needed when they have a
valid event. To my knowledge, both Windows and MacOS already require
applications to request activation in this way, so cross-platform
toolkits don't have to make a special case. This is the first
requirement that was stated before: clients are responsible for
requesting activation when it is appropriate.
I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window. Make
that distinction and the problem is solved; choose whichever stacking
policy you would like. If the distinction between the frame and the
rest of the window is included in the request for activation, you can
even have clicks in the client raise, but only clicks on the frame
activate, though I can think of no reason beyond sadism why anyone
would make things work that way.
I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus. I
believe it would be sensible to keep the active window on top within
its bounds, excepting for secondary windows, like tool palettes, which
should stay above the primary window. This is the stacking behavior
familiar to users of Windows and MacOS. I emphasize that the stacking
policy is independent of the activation policy, so long as the
compositor can distinguish between frames and their contents.
The guides I gave before--clients request activation responsibly,
compositors activate appropriately--allow all users to use their
chosen compositors with any application targeted at Wayland.
The combination of Windows/MacOS-style activation policy with an
active-window-on-top stacking policy is the behavior familiar to
Windows and MacOS users, including the allowance for beginning a
drag-and-drop operation without raising the drag source window. Much
the same system is possible on X11 if window managers will not grab
buttons without modifiers and regular clients will use the globally
active input model, requesting input focus when appropriate. Perhaps
most important to many reading this list is that the all the
activation policies familiar from X are compatible with the client
behavior I have described.
When I'm done with my current project at work, I'll be able to see
about writing code for what I have described, but that's weeks or
months away and then I'll need time to reacquaint myself with pretty
much everything. I hope that this has been a useful message. I
apologize for the lengthy lack of code.
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The lack
of code is ok because I think Rafael is planning to start implementing as
soon as things settle a bit. Sometimes protocol discussions can end up
with a whole lot of hypotheticals and what you gave was a very clear
concise discussion of the topic.

If I am understanding you correctly, what we need are an "activate" request
and "notify_active" and "notify_inactive" events. To support sloppy focus,
clients should just always try to activate on wl_pointer.enter and let the
compositor sort it out unless they have a good reason to do otherwise. For
cases such as alt-tab, or another window closing, the compositor simply
sends a notify_active. I think I'm ok with this.

Two more questions that come to mind:

1) Will we ever need a deactivate request? Under the given scheme, no need
comes immediately to mind.

2) Should the activate be associated with a particular seat. If you have
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.

Once again, Gregory, Thanks for the explanation. I hope I'm following ok.
--Jason Ekstrand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131101/77bc992b/attachment-0001.html>
Jasper St. Pierre
2013-11-02 04:36:31 UTC
Permalink
On Fri, Nov 1, 2013 at 11:58 PM, Jason Ekstrand <jason at jlekstrand.net>wrote:

... snip
Post by Jason Ekstrand
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The lack
of code is ok because I think Rafael is planning to start implementing as
soon as things settle a bit. Sometimes protocol discussions can end up
with a whole lot of hypotheticals and what you gave was a very clear
concise discussion of the topic.
If I am understanding you correctly, what we need are an "activate"
request and "notify_active" and "notify_inactive" events. To support
sloppy focus, clients should just always try to activate on
wl_pointer.enter and let the compositor sort it out unless they have a good
reason to do otherwise. For cases such as alt-tab, or another window
closing, the compositor simply sends a notify_active. I think I'm ok with
this.
1) Will we ever need a deactivate request? Under the given scheme, no
need comes immediately to mind.
No. Well, if we need it, let's add it later.

2) Should the activate be associated with a particular seat. If you have
Post by Jason Ekstrand
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.
I don't think windows need to know which seat they're active on, only that
they're active on possibly one of them. From my eyes, there's nothing that
prevents the compositor to send "notify_active" to more than one window at
the same time for multiseat support.

If I click on an unresponsive window A, we'll send a "click" event to that
window, but since it's unresponsive, it won't activate. I might then decide
to activate another window B, which will respond. When the window A becomes
responsive again, it will process the "click" event and decide to send an
"activate" request back. We need to make sure that this "rogue" client
doesn't steal the focus, so the compositor needs to record the serial for
the last "activate" event it got (sent by window B), and compare against it
when it gets an "activate" event, besides whatever policies it might have.

But serials are seat-specific, so we need the "activate" request to relay
the seat back for the purposes of validating the timestamp. I don't think
it makes sense to expose the active window on wl_seat, though.

Once again, Gregory, Thanks for the explanation. I hope I'm following ok.
Post by Jason Ekstrand
--Jason Ekstrand
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
--
Jasper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131102/290992b4/attachment-0001.html>
Gregory Merchan
2013-11-02 06:28:13 UTC
Permalink
On Fri, Nov 1, 2013 at 11:36 PM, Jasper St. Pierre
Post by Jasper St. Pierre
On Fri, Nov 1, 2013 at 11:58 PM, Jason Ekstrand <jason at jlekstrand.net>
... snip
Post by Jason Ekstrand
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The lack
of code is ok because I think Rafael is planning to start implementing as
soon as things settle a bit. Sometimes protocol discussions can end up with
a whole lot of hypotheticals and what you gave was a very clear concise
discussion of the topic.
If I am understanding you correctly, what we need are an "activate"
request and "notify_active" and "notify_inactive" events. To support sloppy
focus, clients should just always try to activate on wl_pointer.enter and
let the compositor sort it out unless they have a good reason to do
otherwise. For cases such as alt-tab, or another window closing, the
compositor simply sends a notify_active. I think I'm ok with this.
1) Will we ever need a deactivate request? Under the given scheme, no
need comes immediately to mind.
No. Well, if we need it, let's add it later.
Post by Jason Ekstrand
2) Should the activate be associated with a particular seat. If you have
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.
I don't think windows need to know which seat they're active on, only that
they're active on possibly one of them. From my eyes, there's nothing that
prevents the compositor to send "notify_active" to more than one window at
the same time for multiseat support.
If I click on an unresponsive window A, we'll send a "click" event to that
window, but since it's unresponsive, it won't activate. I might then decide
to activate another window B, which will respond. When the window A becomes
responsive again, it will process the "click" event and decide to send an
"activate" request back. We need to make sure that this "rogue" client
doesn't steal the focus, so the compositor needs to record the serial for
the last "activate" event it got (sent by window B), and compare against it
when it gets an "activate" event, besides whatever policies it might have.
But serials are seat-specific, so we need the "activate" request to relay
the seat back for the purposes of validating the timestamp. I don't think it
makes sense to expose the active window on wl_seat, though.
I did not know that when I suggested using the serials. The button,
key, and touch events all have timestamps, so if the notify_active
event also has a timestamp, the timestamps can serve as the signature,
just as they do on X.

Using the timestamp should also make it easier to sort out rogue clients.

Does Wayland have any of the issues that arise on X due to the latter
being asynchronous? I believe I still have notes somewhere on dealing
with those, though only for X, if they are necessary. It amounts to
little more than the compositor watching the timestamps, but there
were a few other needs for either clients or compostors which I cannot
recall right now.
Jason Ekstrand
2013-11-02 15:50:40 UTC
Permalink
Post by Jasper St. Pierre
... snip
Post by Jason Ekstrand
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The lack
of code is ok because I think Rafael is planning to start implementing as
soon as things settle a bit. Sometimes protocol discussions can end up
with a whole lot of hypotheticals and what you gave was a very clear
concise discussion of the topic.
If I am understanding you correctly, what we need are an "activate"
request and "notify_active" and "notify_inactive" events. To support
sloppy focus, clients should just always try to activate on
wl_pointer.enter and let the compositor sort it out unless they have a good
reason to do otherwise. For cases such as alt-tab, or another window
closing, the compositor simply sends a notify_active. I think I'm ok with
this.
1) Will we ever need a deactivate request? Under the given scheme, no
need comes immediately to mind.
No. Well, if we need it, let's add it later.
2) Should the activate be associated with a particular seat. If you have
Post by Jason Ekstrand
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.
I don't think windows need to know which seat they're active on, only that
they're active on possibly one of them. From my eyes, there's nothing that
prevents the compositor to send "notify_active" to more than one window at
the same time for multiseat support.
If I click on an unresponsive window A, we'll send a "click" event to that
window, but since it's unresponsive, it won't activate. I might then decide
to activate another window B, which will respond. When the window A becomes
responsive again, it will process the "click" event and decide to send an
"activate" request back. We need to make sure that this "rogue" client
doesn't steal the focus, so the compositor needs to record the serial for
the last "activate" event it got (sent by window B), and compare against it
when it gets an "activate" event, besides whatever policies it might have.
Here is the problem. Say you have two pointers P and Q and two and two
windows A and B. P clicks on A and A a is now active. Q clicks on B and
now B is active. Then P goes and clicks on B. However, B is already
active so it doesn't request an activation and A stays active with pointer
P. This assumes we are trusting clients to request activation. The other
option is that we simply force a click-always-activates model and clients
are constantly fighting the compositor just to make modal dialogues work.
Post by Jasper St. Pierre
But serials are seat-specific, so we need the "activate" request to relay
the seat back for the purposes of validating the timestamp. I don't think
it makes sense to expose the active window on wl_seat, though.
That's not correct. Timestamps are seat specific but timestamps are not
the same as serials. Timestamps are local to the seat. Serials are
actually compositor-global in weston and, in order to make things work,
should probably at least be client-global in other compositors.
Post by Jasper St. Pierre
Once again, Gregory, Thanks for the explanation. I hope I'm following ok.
Post by Jason Ekstrand
--Jason Ekstrand
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
--
Jasper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131102/3ab8430d/attachment-0001.html>
Jasper St. Pierre
2013-11-02 16:02:00 UTC
Permalink
Post by Jason Ekstrand
Post by Jasper St. Pierre
... snip
Post by Jason Ekstrand
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The
lack of code is ok because I think Rafael is planning to start implementing
as soon as things settle a bit. Sometimes protocol discussions can end up
with a whole lot of hypotheticals and what you gave was a very clear
concise discussion of the topic.
If I am understanding you correctly, what we need are an "activate"
request and "notify_active" and "notify_inactive" events. To support
sloppy focus, clients should just always try to activate on
wl_pointer.enter and let the compositor sort it out unless they have a good
reason to do otherwise. For cases such as alt-tab, or another window
closing, the compositor simply sends a notify_active. I think I'm ok with
this.
1) Will we ever need a deactivate request? Under the given scheme, no
need comes immediately to mind.
No. Well, if we need it, let's add it later.
2) Should the activate be associated with a particular seat. If you have
Post by Jason Ekstrand
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.
I don't think windows need to know which seat they're active on, only
that they're active on possibly one of them. From my eyes, there's nothing
that prevents the compositor to send "notify_active" to more than one
window at the same time for multiseat support.
If I click on an unresponsive window A, we'll send a "click" event to
that window, but since it's unresponsive, it won't activate. I might then
decide to activate another window B, which will respond. When the window A
becomes responsive again, it will process the "click" event and decide to
send an "activate" request back. We need to make sure that this "rogue"
client doesn't steal the focus, so the compositor needs to record the
serial for the last "activate" event it got (sent by window B), and compare
against it when it gets an "activate" event, besides whatever policies it
might have.
Here is the problem. Say you have two pointers P and Q and two and two
windows A and B. P clicks on A and A a is now active. Q clicks on B and
now B is active. Then P goes and clicks on B. However, B is already
active so it doesn't request an activation and A stays active with pointer
P. This assumes we are trusting clients to request activation. The other
option is that we simply force a click-always-activates model and clients
are constantly fighting the compositor just to make modal dialogues work.
"Already active"? All "notify active" means is "please draw me with a
focused frame". The client should send an "activate" request on every
button press if it wants to be focused when something clicks on it.

As has said before, click-always-activate is broken: if I have window A
activate, and I want to drag something from window B onto window A, we
shouldn't activate window B on click.
Post by Jason Ekstrand
Post by Jasper St. Pierre
But serials are seat-specific, so we need the "activate" request to relay
the seat back for the purposes of validating the timestamp. I don't think
it makes sense to expose the active window on wl_seat, though.
That's not correct. Timestamps are seat specific but timestamps are not
the same as serials. Timestamps are local to the seat. Serials are
actually compositor-global in weston and, in order to make things work,
should probably at least be client-global in other compositors.
I thought serials were intentionally *not* client-global, as we often
compare serials from two different clients. But whether they're seat-global
or compositor-global is something the specification doesn't say. We should
probably clarify that somewhere.
Post by Jason Ekstrand
Post by Jasper St. Pierre
Once again, Gregory, Thanks for the explanation. I hope I'm following ok.
Post by Jason Ekstrand
--Jason Ekstrand
_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel
--
Jasper
--
Jasper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131102/a969330e/attachment.html>
Gregory Merchan
2013-11-02 18:28:43 UTC
Permalink
On Sat, Nov 2, 2013 at 11:02 AM, Jasper St. Pierre
On Sat, Nov 2, 2013 at 11:50 AM, Jason Ekstrand <jason at jlekstrand.net>
On Fri, Nov 1, 2013 at 11:36 PM, Jasper St. Pierre <jstpierre at mecheye.net>
Post by Jasper St. Pierre
On Fri, Nov 1, 2013 at 11:58 PM, Jason Ekstrand <jason at jlekstrand.net>
... snip
Post by Jason Ekstrand
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The
lack of code is ok because I think Rafael is planning to start implementing
as soon as things settle a bit. Sometimes protocol discussions can end up
with a whole lot of hypotheticals and what you gave was a very clear concise
discussion of the topic.
If I am understanding you correctly, what we need are an "activate"
request and "notify_active" and "notify_inactive" events. To support sloppy
focus, clients should just always try to activate on wl_pointer.enter and
let the compositor sort it out unless they have a good reason to do
otherwise. For cases such as alt-tab, or another window closing, the
compositor simply sends a notify_active. I think I'm ok with this.
1) Will we ever need a deactivate request? Under the given scheme, no
need comes immediately to mind.
No. Well, if we need it, let's add it later.
Post by Jason Ekstrand
2) Should the activate be associated with a particular seat. If you
have multiple cursors, you can easily have multiple active windows so this
seems perfectly reasonable. If this is the case, should this be part of
wl_seat or should we keep it in xdg_shell? I'm a little afraid to clutter
wl_seat unnecessarily but this is very quickly starting to look like a seat
focus.
I don't think windows need to know which seat they're active on, only
that they're active on possibly one of them. From my eyes, there's nothing
that prevents the compositor to send "notify_active" to more than one window
at the same time for multiseat support.
If I click on an unresponsive window A, we'll send a "click" event to
that window, but since it's unresponsive, it won't activate. I might then
decide to activate another window B, which will respond. When the window A
becomes responsive again, it will process the "click" event and decide to
send an "activate" request back. We need to make sure that this "rogue"
client doesn't steal the focus, so the compositor needs to record the serial
for the last "activate" event it got (sent by window B), and compare against
it when it gets an "activate" event, besides whatever policies it might
have.
Here is the problem. Say you have two pointers P and Q and two and two
windows A and B. P clicks on A and A a is now active. Q clicks on B and
now B is active. Then P goes and clicks on B. However, B is already active
so it doesn't request an activation and A stays active with pointer P. This
assumes we are trusting clients to request activation. The other option is
that we simply force a click-always-activates model and clients are
constantly fighting the compositor just to make modal dialogues work.
"Already active"? All "notify active" means is "please draw me with a
focused frame". The client should send an "activate" request on every button
press if it wants to be focused when something clicks on it.
As has said before, click-always-activate is broken: if I have window A
activate, and I want to drag something from window B onto window A, we
shouldn't activate window B on click.
We should trust clients to request activation when it is appropriate
for the client; appropriateness is distinct from having a valid
signature from the request.

It is in the self-interest of clients to request activation when
appropriate, so we would be trusting them to act in their
self-interest. This is usually a safe bet. Clients not acting in their
own interest--failing to request activation--will not appeal to users,
and evolutionary pressures may take their course.

The beginning of a drag is not the only event which a client may deem
inappropriate for activation. A client, such as a drawing program,
with a free-floating palette would want for its primary window to
remain active when toggle buttons on the palette are clicked. A more
complicated program might have a palette with non-window-activating
toggle buttons, but other controls which are window activating.

Clients may allow their scroll bars to be used without activating a
window. I think most X-based systems and MacOS send scroll wheel
events to the window under the pointer, and non-window-activating
scroll bars would allow the same function to people without or unable
to use scroll wheels.

Most client authors will use a toolkit, and that toolkit can make the
right behavior easy. The default callback for a button press on a
toolkit widget might request activation. The default for scroll bars
might then override the widget default to allow the aforementioned
use. The default for a text area would override to determine if the
event could be the beginning of a drag and act accordingly. I suppose
a callback system is not necessary; a boolean property like
'activatesWindowOnButtonPress' might be used instead, then the event
handlers can do what they need to do. The default could go either way;
I think Cocoa defaults to not activating and overrides in almost every
subclass.

A sometimes convenient way to handle some of this on X is to rely on
button event fall through. Where the client expresses no interest in
button events, they fall through to the window manager's frame window
and the window manager is then responsible. I don't think there's a
similar thing in Wayland, so that may be irrelevant. I think there is
something like this in Cocoa, but it's been to long since I grokked
that.

Trusting clients to activate is more a matter of trusting the
toolkits, and there are few enough of those to apprise authors of what
is expected.
Post by Jasper St. Pierre
But serials are seat-specific, so we need the "activate" request to relay
the seat back for the purposes of validating the timestamp. I don't think it
makes sense to expose the active window on wl_seat, though.
That's not correct. Timestamps are seat specific but timestamps are not
the same as serials. Timestamps are local to the seat. Serials are
actually compositor-global in weston and, in order to make things work,
should probably at least be client-global in other compositors.
I thought serials were intentionally *not* client-global, as we often
compare serials from two different clients. But whether they're seat-global
or compositor-global is something the specification doesn't say. We should
probably clarify that somewhere.
Whatever is used for the signature, I think the most important thing
is to keep an ordered global sequence, so old signatures don't cause
focus stealing. The rest of signature validation is the second most
important thing. I would place third the ability to transfer valid
signatures, as I described in an earlier message.

I mentioned Cocoa because I remember there being something in it for
handling activation--as an example of what a toolkit might do--but I
can't remember it or find it at the moment; maybe GNUstep had the
documentation? I did run across Apple's guidelines for active,
inactive, main, and key windows, and that may be of interest:
https://developer.apple.com/library/mac/documentation/userexperience/conceptual/applehiguidelines/Windows/Windows.html#//apple_ref/doc/uid/20000961-SW8
Bill Spitzak
2013-11-04 22:29:33 UTC
Permalink
Post by Gregory Merchan
The beginning of a drag is not the only event which a client may deem
inappropriate for activation. A client, such as a drawing program,
with a free-floating palette would want for its primary window to
remain active when toggle buttons on the palette are clicked. A more
complicated program might have a palette with non-window-activating
toggle buttons, but other controls which are window activating.
The client itself is probably active and can activate it's main surface
and not the toolbox on clicks. I think compositors should allow a client
to claim any surface is the active one as long as it thinks some surface
belonging to the client can be active.
Post by Gregory Merchan
Clients may allow their scroll bars to be used without activating a
window.
This is a great example and shows that drag & drop is not the only place
that clients should be responsible for activation.
Post by Gregory Merchan
Most client authors will use a toolkit, and that toolkit can make the
right behavior easy.
Yes, toolkits are the proper place for setting the "this widget works
this way" controls. The problem with X and Windows (and maybe OS/X) is
too much of this setting must be communicated to the compositor through
some kind of ipc, slowing down initialization, making it sometimes
impossible to change the settings, and adding a huge amount of
complexity to the api.
Post by Gregory Merchan
A sometimes convenient way to handle some of this on X is to rely on
button event fall through. Where the client expresses no interest in
button events, they fall through to the window manager's frame window
and the window manager is then responsible. I don't think there's a
similar thing in Wayland, so that may be irrelevant. I think there is
something like this in Cocoa, but it's been to long since I grokked
that.
Wayland provides the compositor move + resize api. The client calls this
in response to button clicks in window borders. This is pretty much the
"fallback" api.

I think this could be improved a little by adding this:

1. A way to tell the compositor to choose whether to drag or resize, and
what borders, based on the mouse position. This is to allow the
compositor to be in charge of how thick the resize edges are.

2. Another call to "preview", indicating that the current mouse position
if clicked will in fact cause the move/resize api to be called. The
compositor can then change the cursor or highlight the edges to show
this. There also has to be a way to turn this preview off.

In the end I hope this will get rid of the need for resize edges and
title bars to take any pixels. Clients will just have to make sure there
is some place near the edges that when clicked cause the move/resize api
to be called. Compositors will still be in control of window edge
snapping, etc.
Bill Spitzak
2013-11-04 22:12:03 UTC
Permalink
Post by Jason Ekstrand
Here is the problem. Say you have two pointers P and Q and two and two
windows A and B. P clicks on A and A a is now active. Q clicks on B
and now B is active. Then P goes and clicks on B. However, B is
already active so it doesn't request an activation and A stays active
with pointer P. This assumes we are trusting clients to request
activation. The other option is that we simply force a
click-always-activates model and clients are constantly fighting the
compositor just to make modal dialogues work.
Clients have to activate themselves on all clicks whether or not they
know they are active. Otherwise it is possible that another client has
grabbed the activation. The client will not see the deactivate until
after the click and has no reason to know it is incorrect, and the
compositor may think the client purposely did not activate itself and
thus cannot fake it either.

Or I guess a client could activate itself on deactivate events and rely
on the compositor ignoring them if it really should not be active but
that sounds more like a kludge.

This has nothing to do with modal dialogs. The client knows what surface
is modal and can send that (rather than the surface the cursor in on)
with the activate request.
Post by Jason Ekstrand
That's not correct. Timestamps are seat specific but timestamps are not
the same as serials. Timestamps are local to the seat. Serials are
actually compositor-global in weston and, in order to make things work,
should probably at least be client-global in other compositors.
Oh that's good news. Okay ignore my previous response about this, sounds
good!
Bill Spitzak
2013-11-04 22:05:54 UTC
Permalink
Post by Jasper St. Pierre
But serials are seat-specific, so we need the "activate" request to
relay the seat back for the purposes of validating the timestamp. I
don't think it makes sense to expose the active window on wl_seat, though.
That is annoying. Is there any reason this is a requirement? Or could
the compositor be required to make up a new serial and put a different
serial on every event?

Don't really like the timestamp idea because you are forced to
artificially put a different timestamp on each event so they can be
distinguished, even if more than one event was triggered by the same
physical action.
Gregory Merchan
2013-11-02 06:14:41 UTC
Permalink
On Fri, Nov 1, 2013 at 8:36 PM, Gregory Merchan <gregory.merchan at gmail.com>
Post by Gregory Merchan
Post by Jason Ekstrand
Post by Jason Ekstrand
Yes, in theory they could read the configuration of the compositor.
I really don't want to build this kind of inconsistency into the system
and I don't see why it's justified.
I think I see what you are getting at. I think a scheme that allows simple
applications to obey the global setting without thinking, but still allows
applications that have a good reason to do tricks with the focus, and also
- The compositor sends an "I want you to activate" event, as you propose.
- The client can respond to this with an "activate" request. Or it could
send an "activate" request at other times if it wants.
- The compositor responds to the "activate" request by either ignoring it
or actually doing the activation.
- The compositor sends an "activated" event that the client can respond to
by redrawing to show the fact that they are activated.
If a client just echoes the "I want you to activate" event then it will
work as you expect. A client could also wait after the event until the mouse
enters a correct location or clicks on the right thing. It could also try to
generate spurious activates but the compositor may ignore them.
I still don't understand why a client would want to not activate. I can see
not wanting to raise, but why not activate?
As Bill mentioned in a follow-up, drag sources would want to not activate.
This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.
First, clients are responsible for requesting activation when it is appropriate.
Second, the compositor always activates when it is appropriate.
The complicated part is determining what is appropriate.
There are 5 activation policies. For each policy, the compositor
activates windows as needed for key traversal (e.g. Alt+Tab), task bar
actions, when an active window goes away, viewport changes, etc. The
compositor also activates windows when a request for activation has
the correct signature. The policies are distinguished by special cases
1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
2. Sloppy: Activates a window when the pointer enters it.
3. Delayed sloppy: Activates a window when the pointer has been within
for a short time.
4. Click-to-focus: Activates a window when it is clicked.
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.
(I suppose a "Delayed PointerRoot" policy is possible, but I've never
seen any discussion of it.)
For each of these policies, another distinction may be made according
to signature required to honor an activation request. The strictest
form is to deny all requests, which is not possible on X11 because
there is no redirection for focus changes. An often desired form for
the correct signature, among X11 users, is that the request must come
from a client which is already activated. For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows. Unless I am mistaken, most attempts at "focus
stealing prevention" have aimed at such a policy. I'm pretty sure I've
seen at least one window manager that will fight with bad programs to
enforce such a policy. On X11, the correct signature is always only
that the timestamp is later than the last focus change timestamp, and
this may be achieved by using CURRENT_TIME. Convention is relied upon
to avoid chaos, that convention is that clients must always use a
valid timestamp to set focus, and there are 4 sources of valid
timestamps: 1) button events, 2) key events, 3) property change
events, and 4) a window manager message. This last source exists to
address the lack of a timestamp in the focus change event of the X
protocol. I will refer to this as the "valid event" signature.
Wayland is a different system and there are more options for the
signature requirement. If I understand the protocol correctly, the
serial field of pointer, keyboard, and touch events could be used as a
signature. (Like X, wl_keyboard::enter does not have a time argument,
so that is not an option.) The strictest form of these
policies--denying all requests--can be achieved because the compositor
is in control; it's like a window manager and an X server combined in
that sense. The "must be active" signature can be implemented by
checking that the serial number came from an event sent to an active
client. The valid event signature can be implemented by checking that
the serial number came from a wl_pointer::button event, a
wl_keyboard::key event, a wl_keyboard::enter event, or wl_touch::down
event.
The compositor is always in control, so clients can request activation
as much as they like without messing things up. Clients cannot prevent
the compositor from implementing any of the five activation policies.
The first four policies require nothing from clients to work as
expected; they are what we've had on X forever. The last policy does
not work unless clients request activation as needed when they have a
valid event. To my knowledge, both Windows and MacOS already require
applications to request activation in this way, so cross-platform
toolkits don't have to make a special case. This is the first
requirement that was stated before: clients are responsible for
requesting activation when it is appropriate.
I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window. Make
that distinction and the problem is solved; choose whichever stacking
policy you would like. If the distinction between the frame and the
rest of the window is included in the request for activation, you can
even have clicks in the client raise, but only clicks on the frame
activate, though I can think of no reason beyond sadism why anyone
would make things work that way.
I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus. I
believe it would be sensible to keep the active window on top within
its bounds, excepting for secondary windows, like tool palettes, which
should stay above the primary window. This is the stacking behavior
familiar to users of Windows and MacOS. I emphasize that the stacking
policy is independent of the activation policy, so long as the
compositor can distinguish between frames and their contents.
The guides I gave before--clients request activation responsibly,
compositors activate appropriately--allow all users to use their
chosen compositors with any application targeted at Wayland.
The combination of Windows/MacOS-style activation policy with an
active-window-on-top stacking policy is the behavior familiar to
Windows and MacOS users, including the allowance for beginning a
drag-and-drop operation without raising the drag source window. Much
the same system is possible on X11 if window managers will not grab
buttons without modifiers and regular clients will use the globally
active input model, requesting input focus when appropriate. Perhaps
most important to many reading this list is that the all the
activation policies familiar from X are compatible with the client
behavior I have described.
When I'm done with my current project at work, I'll be able to see
about writing code for what I have described, but that's weeks or
months away and then I'll need time to reacquaint myself with pretty
much everything. I hope that this has been a useful message. I
apologize for the lengthy lack of code.
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The lack of
code is ok because I think Rafael is planning to start implementing as soon
as things settle a bit. Sometimes protocol discussions can end up with a
whole lot of hypotheticals and what you gave was a very clear concise
discussion of the topic.
If I am understanding you correctly, what we need are an "activate" request
and "notify_active" and "notify_inactive" events. To support sloppy focus,
clients should just always try to activate on wl_pointer.enter and let the
compositor sort it out unless they have a good reason to do otherwise. For
cases such as alt-tab, or another window closing, the compositor simply
sends a notify_active. I think I'm ok with this.
The only difference I understand between the active state and having
the keyboard focus is that a keyboard grab may take away the focus but
should not deactivate the window. In the code I was writing for X over
a year ago, I made use of the mode field in XFocusChangeEvent to
decide whether to treat a window as deactivated; as I recall, there is
always a NotifyNormal focus change mode when focus really goes away. I
don't know how grabs work in Wayland, but I was under the impression
that the activate request would be a request for the keyboard focus,
that wl_keyboard::enter would serve as notify_active, and that
wl_keyboard::leave would serve as notify_inactive. If there are grabs
something like in X, then either a new field in wl_keyboard::enter and
wl_keyboard::leave is needed (like X's mode field), or a separate
active state and events are needed. Between the two, I prefer what you
suggest, a separate state and events; the semantics seem to be
clearer.

Sloppy focus, as a system-wide policy, can be handled by the
compositor without the assistance of client. It would activate the
window whenever the window would receive a wl_pointer::enter event. Am
I misunderstanding how events are handled? I was under the impression
the compositor would be aware of crossing and other events. I believe
it would have to be in order to determine the validity of a request
signature. A compositor not using sloppy focus could indeed ignore
signatures from crossing events, so it would be OK for clients to make
the request in any environment, but if it is not necessary then I
think it should not be done. This allows toolkits and applications to
use very much the same logic whether they are targeted at Wayland, X,
MacOS, or Windows.

Yes, for alt-tab and so forth, the compositor just sends a
notify_active. If the client needs to activate another window instead,
such as a modal dialog which should receive events instead of the
parent window, it would use the signature of the notify_active event
in the request. A a compositor with a strict PointerRoot policy could
ignore the request or honor it with something like XWarpPointer.
(Sorry, I have no idea what the Wayland equivalent would be, if it
exists.)
1) Will we ever need a deactivate request? Under the given scheme, no need
comes immediately to mind.
I don't believe it is needed. I haven't seen anything of the sort on
any other system, though, admittedly, I wasn't looking for it either.
2) Should the activate be associated with a particular seat. If you have
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.
As I understand it, activation should be associated with a particular
seat. I had in mind that the signature of an activation request would
somehow indicate the seat making the request. The serial field of the
relevant events seemed suitable as a signature, and I thought the
compositor would be able to associate the value with a seat. It has
been a while since I looked at Wayland code and example clients, so
I'm very uncertain of my understanding.
Once again, Gregory, Thanks for the explanation. I hope I'm following ok.
--Jason Ekstrand
I believe you are, so I'll throw something else at you. The signature
should be something that can be passed from one program to another
either as an execution argument or in the environment. The reason for
this is to allow one program to execute another program and, in the
absence of any other activity, allow the new program to make a valid
request for activation. For example, if a user double-clicks a file
icon in a file manager to open a file, then the file manager pass the
signature of one of the button events to whichever program opens the
file, so that if the user just waits, activation of the window with
the open file will happen automatically. Task bar, dock, panel, etc.
launchers could do the same. By leaving the initial activation of a
new window to a client, the case of the wrong new window getting focus
can be avoided. The compositor must of course ensure that it only
honors the right request: if a signature from a later event was used
for activation, the request of the newly opened window with the old
signature should be denied. Since the signature on X is a timestamp,
this is handled automatically by the server; the window manager just
needs to take care not to map the window above the active window.

I just remembered another reason for activation to be distinct from
keyboard focus: a desktop environment may want to regard a toplevel
window as still active when one of its secondary windows (e.g. a modal
dialog) has keyboard focus. In a sense it would be a branch of a tree
that is active, though only one node at a time has keyboard focus. If
that is possible, is it necessary to have a request to move the
keyboard focus?

Thank you for receiving this so well. I feared I would be sent to the
dustbin for offering no code.
Bill Spitzak
2013-11-04 22:44:01 UTC
Permalink
Post by Gregory Merchan
The only difference I understand between the active state and having
the keyboard focus is that a keyboard grab may take away the focus but
should not deactivate the window.
Grabs don't change the keyboard focus. Instead the client that did the
grab knows it has the keyboard until it loses it. There are no
focus-lost events sent to the previous surface with focus, it just won't
see any events during this time.

In reality the client doing the grab is going to already have the
keyboard focus. Otherwise the compositor probably would not have allowed it.
Post by Gregory Merchan
In the code I was writing for X over
a year ago, I made use of the mode field in XFocusChangeEvent to
decide whether to treat a window as deactivated; as I recall, there is
always a NotifyNormal focus change mode when focus really goes away.
I would avoid this annoyance by sending only focus/active on events to a
client if already has the same state on another surface. A
focus/active-lost event always means a *different* client got it.
Post by Gregory Merchan
Sloppy focus, as a system-wide policy, can be handled by the
compositor without the assistance of client. It would activate the
window whenever the window would receive a wl_pointer::enter event. Am
I misunderstanding how events are handled?
No the client must be in control and decide it does *not* want to be
activated.
Post by Gregory Merchan
A compositor not using sloppy focus could indeed ignore
signatures from crossing events, so it would be OK for clients to make
the request in any environment, but if it is not necessary then I
think it should not be done.
Now that is an excellent idea, and gets rid of the need for the
compositor to send activate-request events on mouse enter. A simple
client basically activates itself in response to every mouse enter or
click event. The compositor has a setting whether point-to-type is on,
and if it is off it ignores the requests on mouse enter.
Post by Gregory Merchan
I believe you are, so I'll throw something else at you. The signature
should be something that can be passed from one program to another
either as an execution argument or in the environment.
I'm not sure this is the same thing, but I would like to see the ability
of a client to pass the ownership of any object it creates to another
client by passing some kind of signature (which cannot be forged because
it is an encrypted value supplied by the compositor). This would avoid
the current hair in making another client produce a subsurface, what I
propose is the *parent* create the subsurface, sets it up exactly how it
wants, then gets the signature from the compositor and passes this on
the argv to the child process. The child process then uses this in a
"take this object" api and the object is transferred to it.
Post by Gregory Merchan
I just remembered another reason for activation to be distinct from
keyboard focus: a desktop environment may want to regard a toplevel
window as still active when one of its secondary windows (e.g. a modal
dialog) has keyboard focus.
Actually this is relevant if the two windows belong to different
clients, as you propose above. If they belong to the same client I
figured the client would just act as though the child got the keystrokes
even if the compositor sent them to the parent.
Gregory Merchan
2013-11-05 05:27:36 UTC
Permalink
Post by Gregory Merchan
The only difference I understand between the active state and having
the keyboard focus is that a keyboard grab may take away the focus but
should not deactivate the window.
Grabs don't change the keyboard focus. Instead the client that did the grab
knows it has the keyboard until it loses it. There are no focus-lost events
sent to the previous surface with focus, it just won't see any events during
this time.
In reality the client doing the grab is going to already have the keyboard
focus. Otherwise the compositor probably would not have allowed it.
I only know X grabs, which do change keyboard focus, so on the off
chance that Wayland works the same way I say "a keyboard grab _may_
take away focus".
Post by Gregory Merchan
In the code I was writing for X over
a year ago, I made use of the mode field in XFocusChangeEvent to
decide whether to treat a window as deactivated; as I recall, there is
always a NotifyNormal focus change mode when focus really goes away.
I would avoid this annoyance by sending only focus/active on events to a
client if already has the same state on another surface. A focus/active-lost
event always means a *different* client got it.
I was just describing a trick for X, in case it was relevant.
Post by Gregory Merchan
Sloppy focus, as a system-wide policy, can be handled by the
compositor without the assistance of client. It would activate the
window whenever the window would receive a wl_pointer::enter event. Am
I misunderstanding how events are handled?
No the client must be in control and decide it does *not* want to be
activated.
"Sloppy focus, as a system-wide policy" refers to the list of 5
policies which I gave in my first message in this thread. That is a
policy which does not allow clients such control. (Did I mention that
I think that and the rest of the first four policies suck?)
Post by Gregory Merchan
A compositor not using sloppy focus could indeed ignore
signatures from crossing events, so it would be OK for clients to make
the request in any environment, but if it is not necessary then I
think it should not be done.
Now that is an excellent idea, and gets rid of the need for the compositor
to send activate-request events on mouse enter. A simple client basically
activates itself in response to every mouse enter or click event. The
compositor has a setting whether point-to-type is on, and if it is off it
ignores the requests on mouse enter.
And it's an idea that fits in with the 5th policy I described: the
compositor has no special conditions for activation, only the general
conditions shared across policies (like viewport changes) and
responding to requests.

I personally don't like the idea of clients requesting activation on
crossing events, in part because it means more cross-platform
differences, but since the compositor can filter requests according to
event-based signatures, we can all have our way.
Post by Gregory Merchan
I believe you are, so I'll throw something else at you. The signature
should be something that can be passed from one program to another
either as an execution argument or in the environment.
I'm not sure this is the same thing, but I would like to see the ability of
a client to pass the ownership of any object it creates to another client by
passing some kind of signature (which cannot be forged because it is an
encrypted value supplied by the compositor). This would avoid the current
hair in making another client produce a subsurface, what I propose is the
*parent* create the subsurface, sets it up exactly how it wants, then gets
the signature from the compositor and passes this on the argv to the child
process. The child process then uses this in a "take this object" api and
the object is transferred to it.
Post by Gregory Merchan
I just remembered another reason for activation to be distinct from
keyboard focus: a desktop environment may want to regard a toplevel
window as still active when one of its secondary windows (e.g. a modal
dialog) has keyboard focus.
Actually this is relevant if the two windows belong to different clients, as
you propose above. If they belong to the same client I figured the client
would just act as though the child got the keystrokes even if the compositor
sent them to the parent.
Bill Spitzak
2013-11-05 18:36:29 UTC
Permalink
Post by Gregory Merchan
Post by Bill Spitzak
No the client must be in control and decide it does *not* want to be
activated.
"Sloppy focus, as a system-wide policy" refers to the list of 5
policies which I gave in my first message in this thread. That is a
policy which does not allow clients such control. (Did I mention that
I think that and the rest of the first four policies suck?)
I *think* we are both describing the same thing (your "policy 5") but
using different terms. Wayland should only have exactly one "policy"
which I will try to describe, to see if we are talking about the same thing:

- The compositor can send a "activate request event" saying that it
would like the client to activate.

- The client can send "activate request". This can be atomically
combined with other changes to surfaces such as resizing, changing
buffers, raising, and mapping/unmapping.

- The compositor can ignore the request, in which case it sends a
"deactivate event" so the client knows it did not happen (note that I
really want mis-matched activate/deactivate events or this is
impossible!). Or

- The compositor can obey the request. If it receives requests
out-of-order from multiple clients it is expected to do a reasonable job
of replicating the result of them being in-order.

Things that are *not* allowed:

- The compositor cannot do any of these actions unless the client
requests it (this is not physically enforced but clients assume it).

- The client cannot force anything to happen. It's request can always be
ignored.

Now the question is how to get the "policies" that the user sees. I see
three ways of doing this. To simplify lets assume only sloppy focus and
click-to-type are wanted:

1. My proposal: Client knows which policy is in effect. If sloppy focus
it sends an activate request on mouse enter. If click-to-type it sends
it on mouse clicks. Compositor obeys these. The annoyance here is that
clients may disagree about policy.

2. Jason's proposal: Compositor knows which policy is in effect. If
sloppy focus it sends an activate request event on mouse enter, if
click-to-type it sends it on mouse clicks. Client echoes these as
activate requests and the compositor obeys these. The annoyance here is
that non-trivial clients will need to figure out why it was sent the
activate request event because it has to treat Alt-Tab differently than
mouse-enter.

3. Your proposal: Client sends activate requests on *both* mouse-enter
and mouse clicks. Compositor knows which policy is in effect, and
ignores the incorrect activate requests. A problem I see is that to get
glitch-free update the client will have to figure out if sloppy focus is
on so it knows whether to draw surfaces activated when sending the
request on mouse enter. However I feel this is not a huge bug and thus
like this the best now.
Post by Gregory Merchan
Post by Bill Spitzak
Post by Gregory Merchan
A compositor not using sloppy focus could indeed ignore
signatures from crossing events, so it would be OK for clients to make
the request in any environment, but if it is not necessary then I
think it should not be done.
Gregory Merchan
2013-11-05 21:12:11 UTC
Permalink
Post by Gregory Merchan
Post by Bill Spitzak
No the client must be in control and decide it does *not* want to be
activated.
"Sloppy focus, as a system-wide policy" refers to the list of 5
policies which I gave in my first message in this thread. That is a
policy which does not allow clients such control. (Did I mention that
I think that and the rest of the first four policies suck?)
I *think* we are both describing the same thing (your "policy 5") but using
different terms. . . .
No. I am describing the map. You are describing the path you want to take on it.
. . . Wayland should only have exactly one "policy" . . .
That's not up to me. I don't think it's necessary to require a policy
for compositors. On the other hand, years of X have produced infinite
varieties of what is for most computer users the wrong thing, and not
one instance of "the right thing", so I do not think it would be
unwise to (at the very least) favor the 5th policy I gave.
. . . which I will
- The compositor can send a "activate request event" saying that it would
like the client to activate.
That is not what I described, mostly because I kept the new things to
a minimum. It seems I hinted at but failed to explicitly mention what
serves much the same purpose: the activation event could provide the
signature for client activation requests. The hint was in my
description of the convention for valid timestamps [ 4) a window
manager message ] on X11, but I failed to mention an analog when I
spoke of signatures in terms of Wayland events. This allows a client
with a compositor-activated surface to instead activate another
surface, but does not allow a refusal of activation except to make the
surface incapable of activation, for example by destroying it.

It is perhaps insufficient to have the compositor request that the
client make a request without providing a reason for the compositor's
request. The client would need to know if it being asked to activate
itself because of Alt+Tab-like switch, viewport changes, or any of the
other reasons a compositor might make the request of a client. This
probably means another enumeration needs to be defined, and how might
that enumeration grow?

Ultimately it falls upon the compositor to activate a surface. Without
some byzantine capabilities system hidden away from compositors, the
compositor must have the power to activate, even if as a matter of
convention it only does so after asking.
- The client can send "activate request". This can be atomically combined
with other changes to surfaces such as resizing, changing buffers, raising,
and mapping/unmapping.
I don't know about "atomically combining", but I did describe an
activation request.
- The compositor can ignore the request, in which case it sends a
"deactivate event" so the client knows it did not happen (note that I really
want mis-matched activate/deactivate events or this is impossible!). Or
I described a compositor ignoring requests with an invalid signature.
A "deactivate event" is not what I described; sending such an event is
negating, not ignoring. What I have described leaves the client
unaware that its request has been declined. The desktop issue of a
client seeking attention (and, so, a task bar blinking or something)
can be handled without the client receiving a denial; it would just
ask for attention in addition to or soon after asking for activation.
- The compositor can obey the request. If it receives requests out-of-order
from multiple clients it is expected to do a reasonable job of replicating
the result of them being in-order.
I would say "honor" the request, but basically that's what I
described. The signature should contain enough information for the
compositor to do the right thing. (On X that is just the refusal of
SetInputFocus with a timestamp earlier than the last setting of
focus.)
- The compositor cannot do any of these actions unless the client requests
it (this is not physically enforced but clients assume it).
As before, this is not what I described. In my description, the
compositor does not make requests of clients when doing things like
changing viewports, but clients can reject activation by withdrawing
the activated surface. See above for the rest.
- The client cannot force anything to happen. It's request can always be
ignored.
Yup.
Now the question is how to get the "policies" that the user sees. I see
three ways of doing this. To simplify lets assume only sloppy focus and
1. My proposal: Client knows which policy is in effect. If sloppy focus it
sends an activate request on mouse enter. If click-to-type it sends it on
mouse clicks. Compositor obeys these. The annoyance here is that clients may
disagree about policy.
2. Jason's proposal: Compositor knows which policy is in effect. If sloppy
focus it sends an activate request event on mouse enter, if click-to-type it
sends it on mouse clicks. Client echoes these as activate requests and the
compositor obeys these. The annoyance here is that non-trivial clients will
need to figure out why it was sent the activate request event because it has
to treat Alt-Tab differently than mouse-enter.
3. Your proposal: Client sends activate requests on *both* mouse-enter and
mouse clicks. Compositor knows which policy is in effect, and ignores the
incorrect activate requests. A problem I see is that to get glitch-free
update the client will have to figure out if sloppy focus is on so it knows
whether to draw surfaces activated when sending the request on mouse enter.
However I feel this is not a huge bug and thus like this the best now.
Post by Gregory Merchan
Post by Bill Spitzak
Post by Gregory Merchan
A compositor not using sloppy focus could indeed ignore
signatures from crossing events, so it would be OK for clients to make
the request in any environment, but if it is not necessary then I
think it should not be done.
I think it's overstating to say I've put forth such a proposal. I
indicated some possibilities and my preference, but I was trying to
avoid putting forth a complete proposal. I was hoping to avoid what
you describe as my proposal for parity with X, on which conventional
clients do not use crossing events to request focus.

What you've described regarding sloppy focus--specifically, clients
that might activate only when the pointer is in a particular
control--is something I've never even seen suggested before. I think
it might be helpful if you provided a description of how a system with
such fine-grained sloppy focus would work and what the benefits would
be over other systems. Perhaps just email me privately or post a link,
if it's too off topic for this list.
Bill Spitzak
2013-11-05 22:31:56 UTC
Permalink
Post by Gregory Merchan
- The compositor can send a "activate request event" saying that it would
like the client to activate.
That is not what I described, mostly because I kept the new things to
a minimum. It seems I hinted at but failed to explicitly mention what
serves much the same purpose: the activation event could provide the
signature for client activation requests. The hint was in my
description of the convention for valid timestamps [ 4) a window
manager message ] on X11, but I failed to mention an analog when I
spoke of signatures in terms of Wayland events. This allows a client
with a compositor-activated surface to instead activate another
surface, but does not allow a refusal of activation except to make the
surface incapable of activation, for example by destroying it.
Okay I think I understand now. Your scheme there is only
activate/deactivate events and an activate request from the client. I
think it will work and getting rid of 1/3 of the api (the activate
request event) is a huge win.

Since the client is entirely in control of the appearance of it's
surfaces, it can make it look like any surface is activated, without
glitches. It can then correct the compositor's pov by telling it with an
activation request of the correct surface. If the compositor has some
kind of pager/thumbnail display with some highlighting showing the
active surface it might be momentarily wrong but maybe those glitches
are ok.
Post by Gregory Merchan
It is perhaps insufficient to have the compositor request that the
client make a request without providing a reason for the compositor's
request. The client would need to know if it being asked to activate
itself because of Alt+Tab-like switch, viewport changes, or any of the
other reasons a compositor might make the request of a client. This
probably means another enumeration needs to be defined, and how might
that enumeration grow?
I think/hope it is not necessary to distinguish these. My concern about
compositors sending activate request events on mouse enter and clicks
and the clients needing to distinguish these from alt+tab. But these are
not sent under what you are proposing.
Post by Gregory Merchan
I don't know about "atomically combining", but I did describe an
activation request.
It may not be necessary to atomically combine under what you propose.
Post by Gregory Merchan
A "deactivate event" is not what I described; sending such an event is
negating, not ignoring. What I have described leaves the client
unaware that its request has been declined.
I would like a client sending an activate request to be able to assume
it is going to get the activation and update all it's surfaces as though
it had them, this will avoid one redraw and remove one round trip before
the screen is updated. But this will require that it get some indication
of failure so it can fix the display when this does not work.
Post by Gregory Merchan
I think it's overstating to say I've put forth such a proposal. I
indicated some possibilities and my preference, but I was trying to
avoid putting forth a complete proposal. I was hoping to avoid what
you describe as my proposal for parity with X, on which conventional
clients do not use crossing events to request focus.
I think we are in agreement about what we want, just misunderstanding
each other. Clients *will* use the crossing events to request focus.

The fact that the client gets to decide whether it is click-to-type or
point-to-type is not a problem IMHO. It may even be a feature. There was
some resistance to that which got my discussion here very confused by
trying to come up with a scheme where the compositor decides.
Post by Gregory Merchan
What you've described regarding sloppy focus--specifically, clients
that might activate only when the pointer is in a particular
control--is something I've never even seen suggested before. I think
it might be helpful if you provided a description of how a system with
such fine-grained sloppy focus would work and what the benefits would
be over other systems.
If the "desktop" is a normal client then it has to have a way to say
that the mouse pointing at it does not take focus. If there is a text
field displayed (like if you started to rename an icon on a typical
Windows-style desktop) then it may make sense for the area of this icon
to take focus.

Also a rooted nested window manager could itself do sloppy focus where
the cursor has to point at one of it's windows, rather than the desktop,
to take focus away from one of the outside windows.

Some clients uninterested in text input (like a video player) may want
to require click-to-type (this then gets into how the video transport
keys are managed...)
Gregory Merchan
2013-11-05 23:23:10 UTC
Permalink
Post by Gregory Merchan
- The compositor can send a "activate request event" saying that it would
like the client to activate.
That is not what I described, mostly because I kept the new things to
a minimum. It seems I hinted at but failed to explicitly mention what
serves much the same purpose: the activation event could provide the
signature for client activation requests. The hint was in my
description of the convention for valid timestamps [ 4) a window
manager message ] on X11, but I failed to mention an analog when I
spoke of signatures in terms of Wayland events. This allows a client
with a compositor-activated surface to instead activate another
surface, but does not allow a refusal of activation except to make the
surface incapable of activation, for example by destroying it.
Okay I think I understand now. Your scheme there is only activate/deactivate
events and an activate request from the client. I think it will work and
getting rid of 1/3 of the api (the activate request event) is a huge win.
Since the client is entirely in control of the appearance of it's surfaces,
it can make it look like any surface is activated, without glitches. It can
then correct the compositor's pov by telling it with an activation request
of the correct surface. If the compositor has some kind of pager/thumbnail
display with some highlighting showing the active surface it might be
momentarily wrong but maybe those glitches are ok.
I think the API for marking surfaces transient or otherwise secondary
will obviate some potential glitches. For example, I think most
thumbnailing window switchers I've seen just ignore transients.
Post by Gregory Merchan
It is perhaps insufficient to have the compositor request that the
client make a request without providing a reason for the compositor's
request. The client would need to know if it being asked to activate
itself because of Alt+Tab-like switch, viewport changes, or any of the
other reasons a compositor might make the request of a client. This
probably means another enumeration needs to be defined, and how might
that enumeration grow?
I think/hope it is not necessary to distinguish these. My concern about
compositors sending activate request events on mouse enter and clicks and
the clients needing to distinguish these from alt+tab. But these are not
sent under what you are proposing.
Post by Gregory Merchan
I don't know about "atomically combining", but I did describe an
activation request.
It may not be necessary to atomically combine under what you propose.
Post by Gregory Merchan
A "deactivate event" is not what I described; sending such an event is
negating, not ignoring. What I have described leaves the client
unaware that its request has been declined.
I would like a client sending an activate request to be able to assume it is
going to get the activation and update all it's surfaces as though it had
them, this will avoid one redraw and remove one round trip before the screen
is updated. But this will require that it get some indication of failure so
it can fix the display when this does not work.
I don't think that's a good assumption to make, because I know I won't
be using sloppy focus and I'll then be seeing multiple redraws from
assuming clients responding to crossing events.
Post by Gregory Merchan
I think it's overstating to say I've put forth such a proposal. I
indicated some possibilities and my preference, but I was trying to
avoid putting forth a complete proposal. I was hoping to avoid what
you describe as my proposal for parity with X, on which conventional
clients do not use crossing events to request focus.
I think we are in agreement about what we want, just misunderstanding each
other. Clients *will* use the crossing events to request focus.
I think this is a disagreement, but it can be accommodated on Wayland
because I'll just make sure I use a compositor that rejects crossing
event requests. (A similar policy on X would be a mess for me, because
I could not then avoid sloppy focus.)
The fact that the client gets to decide whether it is click-to-type or
point-to-type is not a problem IMHO. It may even be a feature. There was
some resistance to that which got my discussion here very confused by trying
to come up with a scheme where the compositor decides.
Post by Gregory Merchan
What you've described regarding sloppy focus--specifically, clients
that might activate only when the pointer is in a particular
control--is something I've never even seen suggested before. I think
it might be helpful if you provided a description of how a system with
such fine-grained sloppy focus would work and what the benefits would
be over other systems.
If the "desktop" is a normal client then it has to have a way to say that
the mouse pointing at it does not take focus. If there is a text field
displayed (like if you started to rename an icon on a typical Windows-style
desktop) then it may make sense for the area of this icon to take focus.
Also a rooted nested window manager could itself do sloppy focus where the
cursor has to point at one of it's windows, rather than the desktop, to take
focus away from one of the outside windows.
Some clients uninterested in text input (like a video player) may want to
require click-to-type (this then gets into how the video transport keys are
managed...)
I think I'll have to just think about this for a while. I personally
don't like sloppy focus because I believe a better system can be built
when it is not allowed, but a system with fine-grained sloppy focus
would be very different from any I've considered. This last request
for a description was more personal curiosity than relevant to
Wayland.
Bill Spitzak
2013-11-06 01:29:00 UTC
Permalink
Post by Gregory Merchan
re: glitches in pagers due to incorrect guessing of activated
surface by comnpositor
Post by Gregory Merchan
I think the API for marking surfaces transient or otherwise secondary
will obviate some potential glitches. For example, I think most
thumbnailing window switchers I've seen just ignore transients.
Yes I agree which is why I don't think these glitches are a real problem
Post by Gregory Merchan
I don't think that's a good assumption to make, because I know I won't
be using sloppy focus and I'll then be seeing multiple redraws from
assuming clients responding to crossing events.
Okay, I think I still misunderstood what you are asking for.

I now believe you are asking for clients to always send an activate
request on mouse enter, and the compositor to ignore these if sloppy
focus is not on.

What I was proposing is that the client knows whether sloppy focus is on
or not, and it only sends activate requests on mouse enter if it is on.

I think under your scheme the client could still predict whether it will
get activation, by remembering from the previous mouse-enter whether it
worked or not.

You could also combine both schemes. Both the client and compositor need
sloppy focus turned on for it to work (if they are both reading the same
configuration this is not a problem).
Post by Gregory Merchan
I think I'll have to just think about this for a while. I personally
don't like sloppy focus because I believe a better system can be built
when it is not allowed, but a system with fine-grained sloppy focus
would be very different from any I've considered. This last request
for a description was more personal curiosity than relevant to
Wayland.
My absolute #1 concern is that clients be able to be clicked and respond
to these clicks without raising, activating, or taking the keyboard
focus. The current behavior of Windows and the Gnome window manager make
non-trivial use of multiple windows impossible, and all modern software
has been forced to resort to a single full-screen tiled window with it's
own "window management" to avoid this bug. Gimp is the only well-known
example of a program trying (and failing) to work around the bug. My
software (the Nuke Compositor from The Foundry) will also try to do it
if you turn on "floating parameter windows", and there are configuration
checkmarks to change whether the window manager is Gnome or KDE to try
to get around the bugs, but it really is quite impossible).

Because Windows fixed this for clicks that start a drag & drop for
Explorer, it is easiest to describe this as fixing drag & drop, since
there are far more users familiar with this limited fix than the general
one.

A secondary concern is that point-to-type remain possible, though I am
fine with it only working in clients that understand it, and am also ok
with a global switch to make it not work even if the client wants it.
Bill Spitzak
2013-11-04 22:03:16 UTC
Permalink
Post by Jason Ekstrand
1) Will we ever need a deactivate request? Under the given scheme, no
need comes immediately to mind.
I'm thinking this may be what clients want to do instead of "lower" when
a middle-mouse button in clicked on a window border (if you wish to act
like a lot of X window managers do).

I think a client can fake this by creating a temp surface, transferring
the activation to it, then destroying the surface.
Post by Jason Ekstrand
2) Should the activate be associated with a particular seat. If you
have multiple cursors, you can easily have multiple active windows so
this seems perfectly reasonable. If this is the case, should this be
part of wl_seat or should we keep it in xdg_shell? I'm a little afraid
to clutter wl_seat unnecessarily but this is very quickly starting to
look like a seat focus.
As far as I can tell all current proposals are exactly equivalent to the
keyboard focus for a particular seat. There is no way for them to be
different, thus everything about activation should be merged with
everything about the focus for a seat, into a single set of events and
requests.

However I think these can be separated in that a client can get a
keyboard focus *without* being activated. I see this as a scheme by
which point-to-type will work but drag & drop does not activate the drag
source:

- mouse moves into client's surface and mouse-enter event is sent
- client requests and gets the keyboard focus (but not the activate)
- If the user types a keystroke (that does not start a drag) the client
activates itself
- If instead the user starts a drag the client does not activate.

I have not seen any systems working this way but it does sound useful,
and it makes "activation" different than the keyboard focus. I think in
this case activation would be compositor-wide, or perhaps per-output,
because what it really would do is change the menubar on things like
OS/X and Unity. Perhaps "how many actives there are" is a
compositor-specific detail.
Jason Ekstrand
2013-11-02 03:59:04 UTC
Permalink
On Fri, Nov 1, 2013 at 8:36 PM, Gregory Merchan
Post by antognolli
Post by Jason Ekstrand
Post by Bill Spitzak
Post by Jason Ekstrand
Yes, in theory they could read the configuration of the compositor.
I really don't want to build this kind of inconsistency into the system
and I don't see why it's justified.
I think I see what you are getting at. I think a scheme that allows
simple
Post by Jason Ekstrand
Post by Bill Spitzak
applications to obey the global setting without thinking, but still
allows
Post by Jason Ekstrand
Post by Bill Spitzak
applications that have a good reason to do tricks with the focus, and
also
Post by Jason Ekstrand
Post by Bill Spitzak
- The compositor sends an "I want you to activate" event, as you
propose.
Post by Jason Ekstrand
Post by Bill Spitzak
- The client can respond to this with an "activate" request. Or it could
send an "activate" request at other times if it wants.
- The compositor responds to the "activate" request by either ignoring
it
Post by Jason Ekstrand
Post by Bill Spitzak
or actually doing the activation.
- The compositor sends an "activated" event that the client can respond
to
Post by Jason Ekstrand
Post by Bill Spitzak
by redrawing to show the fact that they are activated.
If a client just echoes the "I want you to activate" event then it will
work as you expect. A client could also wait after the event until the
mouse
Post by Jason Ekstrand
Post by Bill Spitzak
enters a correct location or clicks on the right thing. It could also
try to
Post by Jason Ekstrand
Post by Bill Spitzak
generate spurious activates but the compositor may ignore them.
I still don't understand why a client would want to not activate. I can
see
Post by Jason Ekstrand
not wanting to raise, but why not activate?
As Bill mentioned in a follow-up, drag sources would want to not activate.
This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.
First, clients are responsible for requesting activation when it is appropriate.
Second, the compositor always activates when it is appropriate.
The complicated part is determining what is appropriate.
There are 5 activation policies. For each policy, the compositor
activates windows as needed for key traversal (e.g. Alt+Tab), task bar
actions, when an active window goes away, viewport changes, etc. The
compositor also activates windows when a request for activation has
the correct signature. The policies are distinguished by special cases
1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
2. Sloppy: Activates a window when the pointer enters it.
3. Delayed sloppy: Activates a window when the pointer has been within
for a short time.
4. Click-to-focus: Activates a window when it is clicked.
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.
(I suppose a "Delayed PointerRoot" policy is possible, but I've never
seen any discussion of it.)
For each of these policies, another distinction may be made according
to signature required to honor an activation request. The strictest
form is to deny all requests, which is not possible on X11 because
there is no redirection for focus changes. An often desired form for
the correct signature, among X11 users, is that the request must come
from a client which is already activated. For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows. Unless I am mistaken, most attempts at "focus
stealing prevention" have aimed at such a policy. I'm pretty sure I've
seen at least one window manager that will fight with bad programs to
enforce such a policy. On X11, the correct signature is always only
that the timestamp is later than the last focus change timestamp, and
this may be achieved by using CURRENT_TIME. Convention is relied upon
to avoid chaos, that convention is that clients must always use a
valid timestamp to set focus, and there are 4 sources of valid
timestamps: 1) button events, 2) key events, 3) property change
events, and 4) a window manager message. This last source exists to
address the lack of a timestamp in the focus change event of the X
protocol. I will refer to this as the "valid event" signature.
Wayland is a different system and there are more options for the
signature requirement. If I understand the protocol correctly, the
serial field of pointer, keyboard, and touch events could be used as a
signature. (Like X, wl_keyboard::enter does not have a time argument,
so that is not an option.) The strictest form of these
policies--denying all requests--can be achieved because the compositor
is in control; it's like a window manager and an X server combined in
that sense. The "must be active" signature can be implemented by
checking that the serial number came from an event sent to an active
client. The valid event signature can be implemented by checking that
the serial number came from a wl_pointer::button event, a
wl_keyboard::key event, a wl_keyboard::enter event, or wl_touch::down
event.
The compositor is always in control, so clients can request activation
as much as they like without messing things up. Clients cannot prevent
the compositor from implementing any of the five activation policies.
The first four policies require nothing from clients to work as
expected; they are what we've had on X forever. The last policy does
not work unless clients request activation as needed when they have a
valid event. To my knowledge, both Windows and MacOS already require
applications to request activation in this way, so cross-platform
toolkits don't have to make a special case. This is the first
requirement that was stated before: clients are responsible for
requesting activation when it is appropriate.
I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window. Make
that distinction and the problem is solved; choose whichever stacking
policy you would like. If the distinction between the frame and the
rest of the window is included in the request for activation, you can
even have clicks in the client raise, but only clicks on the frame
activate, though I can think of no reason beyond sadism why anyone
would make things work that way.
I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus. I
believe it would be sensible to keep the active window on top within
its bounds, excepting for secondary windows, like tool palettes, which
should stay above the primary window. This is the stacking behavior
familiar to users of Windows and MacOS. I emphasize that the stacking
policy is independent of the activation policy, so long as the
compositor can distinguish between frames and their contents.
The guides I gave before--clients request activation responsibly,
compositors activate appropriately--allow all users to use their
chosen compositors with any application targeted at Wayland.
The combination of Windows/MacOS-style activation policy with an
active-window-on-top stacking policy is the behavior familiar to
Windows and MacOS users, including the allowance for beginning a
drag-and-drop operation without raising the drag source window. Much
the same system is possible on X11 if window managers will not grab
buttons without modifiers and regular clients will use the globally
active input model, requesting input focus when appropriate. Perhaps
most important to many reading this list is that the all the
activation policies familiar from X are compatible with the client
behavior I have described.
When I'm done with my current project at work, I'll be able to see
about writing code for what I have described, but that's weeks or
months away and then I'll need time to reacquaint myself with pretty
much everything. I hope that this has been a useful message. I
apologize for the lengthy lack of code.
Gregory,
Thank you very much for your e-mail. I think that helps a lot. The lack
of code is ok because I think Rafael is planning to start implementing as
soon as things settle a bit. Sometimes protocol discussions can end up
with a whole lot of hypotheticals and what you gave was a very clear
concise discussion of the topic.

If I am understanding you correctly, what we need are an "activate" request
and "notify_active" and "notify_inactive" events. To support sloppy focus,
clients should just always try to activate on wl_pointer.enter and let the
compositor sort it out unless they have a good reason to do otherwise. For
cases such as alt-tab, or another window closing, the compositor simply
sends a notify_active. I think I'm ok with this.

Two more questions that come to mind:

1) Will we ever need a deactivate request? Under the given scheme, no need
comes immediately to mind.

2) Should the activate be associated with a particular seat. If you have
multiple cursors, you can easily have multiple active windows so this seems
perfectly reasonable. If this is the case, should this be part of wl_seat
or should we keep it in xdg_shell? I'm a little afraid to clutter wl_seat
unnecessarily but this is very quickly starting to look like a seat focus.

Once again, Gregory, Thanks for the explanation. I hope I'm following ok.
--Jason Ekstrand
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131101/8ee91203/attachment.html>
Bill Spitzak
2013-11-04 21:41:31 UTC
Permalink
Post by Gregory Merchan
As Bill mentioned in a follow-up, drag sources would want to not activate.
This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.
I believe you are describing the system I was thinking of, where
Alt+Tab, etc, are done by the compositor directly activating clients,
while point-to-type and click-to-type is entirely the client's
responsibility, in that they activate themselves (and thus can decide
that a click or mouse movement should *not* cause an activation).

Jason Ekstrand's complaint about this is that it takes whether the
system is set to "point to type" or "click to type" out of the
compositor's control. Therefore he would like some kind of communication
from compositor to client saying "you probably should activate now". I
think this might also be an indication of "the compositor will not
ignore an activate from you now". Point-to-type would do this on mouse
enter, click-to-type on mouse clicks.
Post by Gregory Merchan
1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
I think this can be ignored and only sloppy implemented. There is no
difference if the entire screen is filled with non-desktop clients.
Post by Gregory Merchan
2. Sloppy: Activates a window when the pointer enters it.
This is equivalent to "the desktop does not activate when the pointer
enters it". I would like all clients to have this ability, not just the
desktop.
Post by Gregory Merchan
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.
Not sure what you mean here. Windows is pretty much the same as X
click-to-focus. OS/X "eats" the click that activates the application,
but I believe this is entirely done by the client, and a client could in
fact respond to the click if it wanted.
Post by Gregory Merchan
For each of these policies, another distinction may be made according
to signature required to honor an activation request.
The compositor is totally allowed to ignore any activation request. The
most common reason is because another client has activated itself based
on a later event.
Post by Gregory Merchan
For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows.
This is not a problem. In Wayland it is *clients* that are activated,
not "windows". The client is free to draw highlights and blinking
cursors and anything else so that the user thinks some particular
transient window has the keyboard focus, but the compositor is unaware
of this (though info may leak due to the input method text cursor
position?).

It may be useful for a client to tell the compositor which surface it
thinks is active, so that pagers can perhaps highlight this info. This
should be allowed if the client is already active, but has zero effect
on the behavior or events delivered by the compositor.
Post by Gregory Merchan
To my knowledge, both Windows and MacOS already require
applications to request activation in this way
Windows has an elaborate kludge. Basically it acts like X in that clicks
always activate applications. However if the application manages to do
the right system calls so that Windows thinks something is being dragged
it then undoes the activation. This can botch up if the other active app
dies just at this moment.

I don't know about OS/X.

In any case what you want is the way Wayland should work, no matter what
Windows and OS/X really do.
Post by Gregory Merchan
I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
The client must be entirely and 100% in control of stacking. No window
should ever raise unless the client has explicitly sent a raise request.
This must be true otherwise you will have to add the nightmare of a
continuously updating directed acyclic graph of surface relationships,
which would probably double the size of the Wayland api.

Therefore raising on frame clicks only (or any other subset of the
surface) is trivial and the client's responsibility.
Post by Gregory Merchan
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window.
No this is absolutely irrelevant. The compositor NEVER NEVER NEVER
raises a surface unless the client requests it. Therefore it does not
need any knowledge of the areas of the surface!

Remote display on servers that require the server to add borders will
just not do the raising correctly. Hopefully it can be simulated
reasonably well since it will at least have the window tree and it won't
change too often, and the user can find and raise windows by clicking on
the borders for the few cases where it screws up. I would not waste
development time on trying to improve this.
Post by Gregory Merchan
I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus.
IMHO the only actions the client needs are to be able to "raise" a
surface. The compositor will choose exactly what this means, though it
probably means to put it at the top of all similar surfaces. The client
must also be able to set the window tree, and this means that the
compositor should treat a raise of a parent as being immediately
followed by a raise of each child surface, and perform all this atomically.

I suppose there is a need to "lower" a surface which is what clients
might do in response to a middle mouse click on a window border to match
many X window managers. Though this might be the "deactivate request"
that was suggested. I don't think users use this except as an equivalent
to alt+tab.
Gregory Merchan
2013-11-05 05:14:49 UTC
Permalink
Post by Gregory Merchan
As Bill mentioned in a follow-up, drag sources would want to not activate.
This can be handled more simply than described above, without a
special "activate" system. I assume "activation" applies to a window,
not a client.
I believe you are describing the system I was thinking of, where Alt+Tab,
etc, are done by the compositor directly activating clients, while
point-to-type and click-to-type is entirely the client's responsibility, in
that they activate themselves (and thus can decide that a click or mouse
movement should *not* cause an activation).
Jason Ekstrand's complaint about this is that it takes whether the system is
set to "point to type" or "click to type" out of the compositor's control.
Therefore he would like some kind of communication from compositor to client
saying "you probably should activate now". I think this might also be an
indication of "the compositor will not ignore an activate from you now".
Point-to-type would do this on mouse enter, click-to-type on mouse clicks.
Post by Gregory Merchan
1. PointerRoot: Activates a window when the pointer enters it and
deactivates it when the pointer leaves.
I think this can be ignored and only sloppy implemented. There is no
difference if the entire screen is filled with non-desktop clients.
Post by Gregory Merchan
2. Sloppy: Activates a window when the pointer enters it.
This is equivalent to "the desktop does not activate when the pointer enters
it". I would like all clients to have this ability, not just the desktop.
Post by Gregory Merchan
5. Windows/MacOS-style: Does not activate a window, except as it does
for all policies.
Not sure what you mean here. Windows is pretty much the same as X
click-to-focus. OS/X "eats" the click that activates the application, but I
believe this is entirely done by the client, and a client could in fact
respond to the click if it wanted.
Bill, I think you misunderstood what I was trying to do here. I was
describing the various systems that have existed in the way I
understand them which I believes frames the issues so all can be
satisfied. Yes, you and I have reached the same conclusions about some
of this, but I think it's important to lay everything out there,
including the rare PointerRoot policy, so everyone can see what's
going on; I believe the similar issues on X have languished because no
one has been willing to step back far enough to get a good look at
things.

Regarding number 5, I should have been more specific in naming the
style. It is, judging from the Cocoa APIs, the policy of MacOS, but
not of MS Windows. I forget Windows does not do this because (it
seems) they made a special case for Explorer, so that it does not
raise a folder window when a drag may begin; I've never known any
other Windows application to not raise a window on mousedown which may
begin a drag.
Post by Gregory Merchan
For each of these policies, another distinction may be made according
to signature required to honor an activation request.
The compositor is totally allowed to ignore any activation request. The most
common reason is because another client has activated itself based on a
later event.
As before, I'm just laying it all out there. Brief summary:

1. All window management policies set focus without exception in
certain cases. (E.g. Alt+Tab, viewport changes.)
2. The policies may be distinguished first by additional cases in
which they set focus without exception. (The five I mentioned.)
3. Second they may be further distinguished by how they allow clients
to set focus. (Client request filtering based on a signature.)

The order of the last two could be flipped, but I think the taxonomy
is tidier this way. I would personally prefer the 5th policy, but a
lot of people think we must have one of the first 4; the 5th policy
could have been implemented on X, but in almost 20 years no one has
done it.
Post by Gregory Merchan
For example, this allows an
active program to activate a dialog, but prevents other programs from
activating any windows.
This is not a problem. In Wayland it is *clients* that are activated, not
"windows". The client is free to draw highlights and blinking cursors and
anything else so that the user thinks some particular transient window has
the keyboard focus, but the compositor is unaware of this (though info may
leak due to the input method text cursor position?).
It may be useful for a client to tell the compositor which surface it thinks
is active, so that pagers can perhaps highlight this info. This should be
allowed if the client is already active, but has zero effect on the behavior
or events delivered by the compositor.
It was my impression from this discussion that "active" does not yet
have a meaning.
Post by Gregory Merchan
To my knowledge, both Windows and MacOS already require
applications to request activation in this way
Windows has an elaborate kludge. Basically it acts like X in that clicks
always activate applications. However if the application manages to do the
right system calls so that Windows thinks something is being dragged it then
undoes the activation. This can botch up if the other active app dies just
at this moment.
Have you found a way to do it one Windows? I searched the API I could
find and saw nothing, hence I suppose it's a private thing for just
Explorer. (Or whatever their file manager is called.)
I don't know about OS/X.
In any case what you want is the way Wayland should work, no matter what
Windows and OS/X really do.
As the developer of a cross-platform toolkit, I would think you would
appreciate as much parity as possible between platforms. I know I've
seen comments in at least one toolkit's code where a developer
grumbled about some difference between systems that required extra
work or weird hacks. (I think it was Gtk, but the comment is not where
I remember it being.)
Post by Gregory Merchan
I have said nothing about stacking. Handling activation as I have
described allows for every kind of stacking behavior I've seen, except
for one: raise on frame clicks, but not on clicks within the frame.
The client must be entirely and 100% in control of stacking. No window
should ever raise unless the client has explicitly sent a raise request.
This must be true otherwise you will have to add the nightmare of a
continuously updating directed acyclic graph of surface relationships, which
would probably double the size of the Wayland api.
Therefore raising on frame clicks only (or any other subset of the surface)
is trivial and the client's responsibility.
Our notions of "entire and 100% in control" are different. For me that
would mean a client can raise its windows above all others any time
for whatever reason, or, in a word, chaos.

I left stacking out because it is more complicated, and my message was
already long enough. Before compositors, it was really simple because
things like menus and tooltips could just be ignored. Now we expect
menus to have shadows and I don't know what for tooltips, so more
information has to be conveyed between programs.

I believe that the easiest and maybe best stacking policy is that the
compositor only raises windows in response to requests from the active
client. (Which, I think is what you meant, Bill.) But I think this can
be decided separately from the question of how windows are activated
and receive keyboard focus.
Post by Gregory Merchan
This exception exists when the compositor is not responsible for
drawing the window frame, because nothing I have described allows the
compositor to distinguish between parts of the client window.
No this is absolutely irrelevant. The compositor NEVER NEVER NEVER raises a
surface unless the client requests it. Therefore it does not need any
knowledge of the areas of the surface!
I'm inclined to NEVER NEVER NEVER respond to any email that puts
anything in all caps, especially when the person yelling hasn't
understood what I've said.

Let me see if I can put it another way:

"Handling activation as I described it allows for every kind of
stacking behavior except those kinds in which the compositor must be
aware of the contents of the client windows."

Got that? I'm bolstering your case. Stop yelling.
Remote display on servers that require the server to add borders will just
not do the raising correctly. Hopefully it can be simulated reasonably well
since it will at least have the window tree and it won't change too often,
and the user can find and raise windows by clicking on the borders for the
few cases where it screws up. I would not waste development time on trying
to improve this.
Jason has posted patches for frames in Wayland. I don't know what's
going on there because there's no public discussion I can find, and I
thought one reason for Wayland was to get away from that. In any case,
I'm at least aware of something going on, so I give it a passing
mention.
Post by Gregory Merchan
I believe a simple stacking policy would be to allow a client with an
active window to do anything it wants with its windows within the
bounds set by other features; basically it can do anything as long as
it doesn't put windows below stay-on-bottom features, like the
desktop, or above stay-on-top features, like task bars and menus.
Oh. I guess I'm repeating myself and didn't leave out as much as I
thought I did.
IMHO the only actions the client needs are to be able to "raise" a surface.
The compositor will choose exactly what this means, though it probably means
to put it at the top of all similar surfaces. The client must also be able
to set the window tree, and this means that the compositor should treat a
raise of a parent as being immediately followed by a raise of each child
surface, and perform all this atomically.
I suppose there is a need to "lower" a surface which is what clients might
do in response to a middle mouse click on a window border to match many X
window managers. Though this might be the "deactivate request" that was
suggested. I don't think users use this except as an equivalent to alt+tab.
Lowering below other clients' windows in the space of freely moving
windows (not desktop, not OSD, not "on the glass" etc.) is probably
best left to some equally obscure mouse and modifier combination
handled by the compositor. Rearrange the windows of one's own client
is shouldn't be a problem. Something like XRestackWindows() comes to
mind. Of course, that allows the temporary surface trick.
Bill Spitzak
2013-11-05 19:47:11 UTC
Permalink
Post by Gregory Merchan
1. All window management policies set focus without exception in
certain cases. (E.g. Alt+Tab, viewport changes.)
No. All the compositor can do is send a focus-request-event to the
client. The client is allowed to ignore it. The compositor has to
support this anyway because the client may be dead and not responding to
the focus change.

The reason is so that the client can atomically make changes to it's
display, window stacking, and visibility of windows to match the current
focus. This is a Wayland design requirement ("glitch free update") and
there is no way to do this unless the client has final say.
Post by Gregory Merchan
2. The policies may be distinguished first by additional cases in
which they set focus without exception. (The five I mentioned.)
The compositor is not allowed to "set focus without exception". However
the "policies" could be distinguished by when the compositor sends
focus-request-event. It is also possible that the "policy" must be known
by the client.
Post by Gregory Merchan
Post by Bill Spitzak
Windows has an elaborate kludge. Basically it acts like X in that clicks
always activate applications. However if the application manages to do the
right system calls so that Windows thinks something is being dragged it then
undoes the activation. This can botch up if the other active app dies just
at this moment.
Have you found a way to do it one Windows? I searched the API I could
find and saw nothing, hence I suppose it's a private thing for just
Explorer. (Or whatever their file manager is called.)
You may be right that it is a hidden API used by Explorer. I never found
a way. However it is very easy to make *no* clicks raise a window by
just not calling the "dispatch" function. I have not found any way get a
working application by calling "dispatch" sometimes (it seems if you
miss one call it ignores all others). But I felt this was close to a
working approach.
Post by Gregory Merchan
As the developer of a cross-platform toolkit, I would think you would
appreciate as much parity as possible between platforms. I know I've
seen comments in at least one toolkit's code where a developer
grumbled about some difference between systems that required extra
work or weird hacks. (I think it was Gtk, but the comment is not where
I remember it being.)
What I would like is for Wayland to allow maximum freedom for the client
to anything it wants. This then reduces the toolkit writers' pain to
only the *other* platforms, since they can simulate any result they
achieve there on Wayland.

In particular a client must be in absolute total final control over the
window stacking and visiblity and must be able to make it look like the
keyboard focus is on any window as long as the compositor thinks it is
on some window belonging to the same client.
Post by Gregory Merchan
Our notions of "entire and 100% in control" are different. For me that
would mean a client can raise its windows above all others any time
for whatever reason, or, in a word, chaos.
I mean that a window is not raised (or mapped or unmapped) unless the
client requests it. This is so that it is impossible for the compositor
to place windows in a stacking order different than the client wants.

The compositor is allowed to ignore requests. I hope this will be
designed to be very lenient, with the primary design goal to prevent
hostile clients, rather than trying to enforce user interface rules. But
the boundary is pretty vague.
Post by Gregory Merchan
Post by Bill Spitzak
No this is absolutely irrelevant. The compositor NEVER NEVER NEVER raises a
surface unless the client requests it. Therefore it does not need any
knowledge of the areas of the surface!
I'm inclined to NEVER NEVER NEVER respond to any email that puts
anything in all caps, especially when the person yelling hasn't
understood what I've said.
Sorry. However I am very concerned with any proposal that sounds like
the client does not have final say. This will violate the Wayland design
criteria of glitch-free update because the client will have to redraw
and map/unmap/restack windows to "fix" the result after the compositor
does it.
Post by Gregory Merchan
Jason has posted patches for frames in Wayland.
I think there will have to be support for compositor-supplied frames,
but I think the main reason is to support remote display on a legacy
system where it is impractical to remove the remote display's frames.
Also the current fullscreen already can tell the client to not draw
frames so this should be merged. And it may be useful for tiling and
tabbing and other experimental window management.

The "frame" and "titlebar" should be distinguished. A "maximized" app
should have a titlebar but no frame (this is currently ignored by
Wayland and lots of X window managers, I am unclear why people cannot
see this bug!).

I would limit the api to the compositor being able to tell the client
whether to draw the frame and titlebar. This may have to be merged with
the configure request event. And minimal information from the client: a
UTF-8 window name (null for no frame), an icon surface, and the window
parenting tree are all you get.

I am not at all happy with KDE's idea to replicate legacy systems
unnecessarily in a Wayland compositor. To correctly do compositor frames
an *enormous* amount of crap needs to be communicated from the client to
the compositor, which like ICCCM and _NET_WM_* will quickly become
bigger and more bug-ridden than the rest of the Wayland api.
Post by Gregory Merchan
Lowering below other clients' windows in the space of freely moving
windows (not desktop, not OSD, not "on the glass" etc.) is probably
best left to some equally obscure mouse and modifier combination
handled by the compositor.
I certainly rely on middle-mouse-click on title to lower all the time
and would not be happy if it is impossible. However it may be acceptable
if this is done by the compositor move/resize fallback for handling events.
Post by Gregory Merchan
Rearrange the windows of one's own client
is shouldn't be a problem. Something like XRestackWindows() comes to
mind. Of course, that allows the temporary surface trick.
I think a client can get any order it wants by changing the window
parent tree and then raising the bottommost window that is in the
"wrong" place. No other api is needed.
Gregory Merchan
2013-11-05 22:49:28 UTC
Permalink
Post by Gregory Merchan
1. All window management policies set focus without exception in
certain cases. (E.g. Alt+Tab, viewport changes.)
No. All the compositor can do is send a focus-request-event to the client.
The client is allowed to ignore it. The compositor has to support this
anyway because the client may be dead and not responding to the focus
change.
The reason is so that the client can atomically make changes to it's
display, window stacking, and visibility of windows to match the current
focus. This is a Wayland design requirement ("glitch free update") and there
is no way to do this unless the client has final say.
Now I understand what you meant by "atomically" in a previous message.

I don't know near well enough how Wayland actually works, so let me
see if I can elaborate the differences between what we've described.
I'm going to assume that somehow the client knows that it should not
reject the compositor's request; for example, the user has changed the
viewport and the client is the one the compositor believes should be
activated. I'll call the compositor 'W' and the client to be activated
'A', the client to be deactivated 'Z'

Viewport change as described by Bill:
W to A: Request activation.
A to W: Activate me and do these things, or don't activate me at all.
W to Z: (1) You are deactivated; (2) Nothing.
W to A: (1) You are activated (and by other events or by implication
everything is done.); (2) You are not activated (and by implication
those things are not done.)

If A was not activated, the compositor does the same with B, C, D, . .
.. Z only receives the deactivation event when another client has
accepted.

Do I describe what happens to Z correctly?

Viewport change as described by Greg:
W to Z: You are deactivated.
W to A: You are activated.
A to W: Do these things.
(By events or by convention everything is done.)


I believe the compositor to client request must include a reason for
the request if the client is allowed to completely refuse, so that it
does not refuse in reasonable events like viewport changes. I think
this makes things needlessly complicated.

On the other hand, if the client must make the request, it doesn't get
complicated. The request and other changes can still happen
atomically. (This, incidentally, is how I believe globally active
clients on X11 should be treated. The WM_TAKE_FOCUS message should
only be sent when the client should not refuse focus because it would
mess up normal operations. Window managers should not grab buttons in
the client area, because the client knows best how to handle button
presses and it should interpret the WM_TAKE_FOCUS message as being
from events it knows nothing about.)
Post by Gregory Merchan
2. The policies may be distinguished first by additional cases in
which they set focus without exception. (The five I mentioned.)
The compositor is not allowed to "set focus without exception". However the
"policies" could be distinguished by when the compositor sends
focus-request-event. It is also possible that the "policy" must be known by
the client.
Here we're just describing different systems, as explained above.
Post by Gregory Merchan
Post by Bill Spitzak
Windows has an elaborate kludge. Basically it acts like X in that clicks
always activate applications. However if the application manages to do the
right system calls so that Windows thinks something is being dragged it then
undoes the activation. This can botch up if the other active app dies just
at this moment.
Have you found a way to do it one Windows? I searched the API I could
find and saw nothing, hence I suppose it's a private thing for just
Explorer. (Or whatever their file manager is called.)
You may be right that it is a hidden API used by Explorer. I never found a
way. However it is very easy to make *no* clicks raise a window by just not
calling the "dispatch" function. I have not found any way get a working
application by calling "dispatch" sometimes (it seems if you miss one call
it ignores all others). But I felt this was close to a working approach.
Post by Gregory Merchan
As the developer of a cross-platform toolkit, I would think you would
appreciate as much parity as possible between platforms. I know I've
seen comments in at least one toolkit's code where a developer
grumbled about some difference between systems that required extra
work or weird hacks. (I think it was Gtk, but the comment is not where
I remember it being.)
What I would like is for Wayland to allow maximum freedom for the client to
anything it wants. This then reduces the toolkit writers' pain to only the
*other* platforms, since they can simulate any result they achieve there on
Wayland.
In particular a client must be in absolute total final control over the
window stacking and visiblity and must be able to make it look like the
keyboard focus is on any window as long as the compositor thinks it is on
some window belonging to the same client.
I suspect the cost of the freedom to reject activation is too high,
but the cost of letting the client specify how to be activated is not
too high. (Basically, what I said above.) This is just an impression;
I haven't tried to lay it all out enough to even say it's my opinion,
much less than to assert it is so.
Post by Gregory Merchan
Our notions of "entire and 100% in control" are different. For me that
would mean a client can raise its windows above all others any time
for whatever reason, or, in a word, chaos.
I mean that a window is not raised (or mapped or unmapped) unless the client
requests it. This is so that it is impossible for the compositor to place
windows in a stacking order different than the client wants.
The compositor is allowed to ignore requests. I hope this will be designed
to be very lenient, with the primary design goal to prevent hostile clients,
rather than trying to enforce user interface rules. But the boundary is
pretty vague.
Post by Gregory Merchan
Post by Bill Spitzak
No this is absolutely irrelevant. The compositor NEVER NEVER NEVER raises a
surface unless the client requests it. Therefore it does not need any
knowledge of the areas of the surface!
I'm inclined to NEVER NEVER NEVER respond to any email that puts
anything in all caps, especially when the person yelling hasn't
understood what I've said.
Sorry. However I am very concerned with any proposal that sounds like the
client does not have final say. This will violate the Wayland design
criteria of glitch-free update because the client will have to redraw and
map/unmap/restack windows to "fix" the result after the compositor does it.
Post by Gregory Merchan
Jason has posted patches for frames in Wayland.
I think there will have to be support for compositor-supplied frames, but I
think the main reason is to support remote display on a legacy system where
it is impractical to remove the remote display's frames. Also the current
fullscreen already can tell the client to not draw frames so this should be
merged. And it may be useful for tiling and tabbing and other experimental
window management.
The "frame" and "titlebar" should be distinguished. A "maximized" app should
have a titlebar but no frame (this is currently ignored by Wayland and lots
of X window managers, I am unclear why people cannot see this bug!).
I would limit the api to the compositor being able to tell the client
whether to draw the frame and titlebar. This may have to be merged with the
configure request event. And minimal information from the client: a UTF-8
window name (null for no frame), an icon surface, and the window parenting
tree are all you get.
I am not at all happy with KDE's idea to replicate legacy systems
unnecessarily in a Wayland compositor. To correctly do compositor frames an
*enormous* amount of crap needs to be communicated from the client to the
compositor, which like ICCCM and _NET_WM_* will quickly become bigger and
more bug-ridden than the rest of the Wayland api.
Post by Gregory Merchan
Lowering below other clients' windows in the space of freely moving
windows (not desktop, not OSD, not "on the glass" etc.) is probably
best left to some equally obscure mouse and modifier combination
handled by the compositor.
I certainly rely on middle-mouse-click on title to lower all the time and
would not be happy if it is impossible. However it may be acceptable if this
is done by the compositor move/resize fallback for handling events.
Post by Gregory Merchan
Rearrange the windows of one's own client
is shouldn't be a problem. Something like XRestackWindows() comes to
mind. Of course, that allows the temporary surface trick.
I think a client can get any order it wants by changing the window parent
tree and then raising the bottommost window that is in the "wrong" place. No
other api is needed.
Bill Spitzak
2013-11-06 01:47:09 UTC
Permalink
Post by Gregory Merchan
W to A: Request activation.
A to W: Activate me and do these things, or don't activate me at all.
W to Z: (1) You are deactivated; (2) Nothing.
W to A: (1) You are activated (and by other events or by implication
everything is done.); (2) You are not activated (and by implication
those things are not done.)
If A was not activated, the compositor does the same with B, C, D, . .
.. Z only receives the deactivation event when another client has
accepted.
Do I describe what happens to Z correctly?
I think you described pretty much what I was considering, though I never
even thought about it needing to reject the associated operations. But
in any case...
Post by Gregory Merchan
W to Z: You are deactivated.
W to A: You are activated.
A to W: Do these things.
(By events or by convention everything is done.)
I am now convinced that what you want will work and is simpler.

I think I proposed sort of the same thing initially, but in my version
the client was in charge of whether sloppy focus worked because I only
said the compositor would ignore obviously-hostile clients. IMHO this
was not a problem but others here certainly did not like it. I then made
a big mistake by thinking this requied some kind of advisory activate
event from the compositor.

In your scheme the client can try to activate on mouse enter but the
compositor ignores it, achieving the same result of having the
compositor in control of focus policy and avoiding the advisory activate
event.
Post by Gregory Merchan
I believe the compositor to client request must include a reason for
the request if the client is allowed to completely refuse, so that it
does not refuse in reasonable events like viewport changes. I think
this makes things needlessly complicated.
On the other hand, if the client must make the request, it doesn't get
complicated. The request and other changes can still happen
atomically.
I suspect the cost of the freedom to reject activation is too high,
but the cost of letting the client specify how to be activated is not
too high. (Basically, what I said above.) This is just an impression;
I haven't tried to lay it all out enough to even say it's my opinion,
much less than to assert it is so.
I agree with all this analysis.

This is good. Lets see if anybody else is following this.

Rafael Antognolli
2013-10-15 15:17:31 UTC
Permalink
Hi Pekka,

I just updated it to cover what you mentioned. The diff from the
previous one is:

http://pastebin.ca/2466952

I also removed the parts where the protocol file is added to the build
system, so we can cover that later (if only the .xml is going to be
installed on the system with a .pc, or if it's going to be built into
the wayland library).

Thanks for the reviews,
Rafael
Post by antognolli
From: Rafael Antognolli <rafael.antognolli at intel.com>
xdg_shell is a protocol aimed to substitute wl_shell in the long term,
but will not be part of the wayland core protocol. It starts as a
non-stable API, aimed to be used as a development place at first, and
once features are defined as required by several desktop shells, we can
finally make it stable.
---
protocol/Makefile.am | 2 +-
protocol/xdg-surface.xml | 336 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 337 insertions(+), 1 deletion(-)
create mode 100644 protocol/xdg-surface.xml
diff --git a/protocol/Makefile.am b/protocol/Makefile.am
index cc9cd1c..5f26d77 100644
--- a/protocol/Makefile.am
+++ b/protocol/Makefile.am
@@ -1 +1 @@
-dist_pkgdata_DATA = wayland.xml
+dist_pkgdata_DATA = wayland.xml xdg-surface.xml
diff --git a/protocol/xdg-surface.xml b/protocol/xdg-surface.xml
new file mode 100644
index 0000000..4d2cc1b
--- /dev/null
+++ b/protocol/xdg-surface.xml
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="xdg_surface">
+
+ <copyright>
+ Copyright ? 2008-2013 Kristian H?gsberg
+ Copyright ? 2013 Rafael Antognolli
+ Copyright ? 2010-2013 Intel Corporation
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the copyright holders not be used in advertising or publicity
+ pertaining to distribution of the software without specific,
+ written prior permission. The copyright holders make no
+ representations about the suitability of this software for any
+ purpose. It is provided "as is" without express or implied
+ warranty.
+
+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ THIS SOFTWARE.
+ </copyright>
+
+ <interface name="xdg_shell" version="1">
+ <description summary="create desktop-style surfaces">
+ This interface is implemented by servers that provide
+ desktop-style user interfaces.
+
+ It allows clients to associate a xdg_surface with
+ a basic surface.
+ </description>
+
+ <request name="get_xdg_surface">
+ <description summary="create a shell surface from a surface">
+ Create a shell surface for an existing surface.
+
+ Only one shell surface can be associated with a given surface.
+ </description>
+ <arg name="id" type="new_id" interface="xdg_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="xdg_surface" version="1">
+
+ <description summary="desktop-style metadata interface">
+ An interface that may be implemented by a wl_surface, for
+ implementations that provide a desktop-style user interface.
+
+ It provides requests to treat surfaces like toplevel, fullscreen
+ or popup windows, move, resize or maximize them, associate
+ metadata like title and class, etc.
+
+ On the server side the object is automatically destroyed when
+ the related wl_surface is destroyed. On client side,
+ xdg_surface_destroy() must be called before destroying
+ the wl_surface object.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="remove xdg_surface interface">
+ The xdg_surface interface is removed from the wl_surface object
+ that was turned into a xdg_surface with
+ xdg_shell.get_xdg_surface request. The xdg_surface properties,
+ like maximized and fullscreen, are lost. The wl_surface loses
+ its role as a xdg_surface. The wl_surface is unmapped.
+ </description>
+ </request>
+
+ <request name="pong">
+ <description summary="respond to a ping event">
+ A client must respond to a ping event with a pong request or
+ the client may be deemed unresponsive.
+ </description>
+ <arg name="serial" type="uint" summary="serial of the ping event"/>
+ </request>
+
+ <request name="move">
+ <description summary="start an interactive move">
+ Start a pointer-driven move of the surface.
+
+ This request must be used in response to a button press event.
+ The server may ignore move requests depending on the state of
+ the surface (e.g. fullscreen or maximized).
+ </description>
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ </request>
+
+ <enum name="resize">
+ <description summary="edge values for resizing">
+ These values are used to indicate which edge of a surface
+ is being dragged in a resize operation. The server may
+ use this information to adapt its behavior, e.g. choose
+ an appropriate cursor image.
+ </description>
+ <entry name="none" value="0"/>
+ <entry name="top" value="1"/>
+ <entry name="bottom" value="2"/>
+ <entry name="left" value="4"/>
+ <entry name="top_left" value="5"/>
+ <entry name="bottom_left" value="6"/>
+ <entry name="right" value="8"/>
+ <entry name="top_right" value="9"/>
+ <entry name="bottom_right" value="10"/>
+ </enum>
+
+ <request name="resize">
+ <description summary="start an interactive resize">
+ Start a pointer-driven resizing of the surface.
+
+ This request must be used in response to a button press event.
+ The server may ignore resize requests depending on the state of
+ the surface (e.g. fullscreen or maximized).
+ </description>
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
+ </request>
+
+ <request name="set_toplevel">
+ <description summary="make the surface a toplevel surface">
+ Map the surface as a toplevel surface.
+
+ A toplevel surface is not fullscreen, maximized or transient.
+ </description>
+ </request>
+
+ <enum name="transient">
+ <description summary="details of transient behaviour">
+ These flags specify details of the expected behaviour
+ of transient surfaces. Used in the set_transient request.
+ </description>
+ <entry name="inactive" value="0x1" summary="do not set keyboard focus"/>
+ </enum>
+
+ <request name="set_transient">
+ <description summary="make the surface a transient surface">
+ Map the surface relative to an existing surface.
+
+ The x and y arguments specify the locations of the upper left
+ corner of the surface relative to the upper left corner of the
+ parent surface, in surface local coordinates.
+
+ The flags argument controls details of the transient behaviour.
+ </description>
+
+ <arg name="parent" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="flags" type="uint"/>
+ </request>
+
+ <enum name="fullscreen_method">
+ <description summary="different method to set the surface fullscreen">
+ Hints to indicate to the compositor how to deal with a conflict
+ between the dimensions of the surface and the dimensions of the
+ output. The compositor is free to ignore this parameter.
+ </description>
+ <entry name="default" value="0" summary="no preference, apply default policy"/>
+ <entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
+ <entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
+ <entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
+ </enum>
+
+ <request name="set_fullscreen">
+ <description summary="make the surface a fullscreen surface">
+ Map the surface as a fullscreen surface.
+
+ If an output parameter is given then the surface will be made
+ fullscreen on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The client may specify a method to resolve a size conflict
+ between the output size and the surface size - this is provided
+ through the method parameter.
+
+ The framerate parameter is used only when the method is set
+ to "driver", to indicate the preferred framerate. A value of 0
+ indicates that the app does not care about framerate. The
+ framerate is specified in mHz, that is framerate of 60000 is 60Hz.
+
+ A method of "scale" or "driver" implies a scaling operation of
+ the surface, either via a direct scaling operation or a change of
+ the output mode. This will override any kind of output scaling, so
+ that mapping a surface with a buffer size equal to the mode can
+ fill the screen independent of buffer_scale.
+
+ A method of "fill" means we don't scale up the buffer, however
+ any output scale is applied. This means that you may run into
+ an edge case where the application maps a buffer with the same
+ size of the output mode but buffer_scale 1 (thus making a
+ surface larger than the output). In this case it is allowed to
+ downscale the results to fit the screen.
+
+ The compositor must reply to this request with a configure event
+ with the dimensions for the output on which the surface will
+ be made fullscreen.
+ </description>
+ <arg name="method" type="uint"/>
+ <arg name="framerate" type="uint"/>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="set_popup">
+ <description summary="make the surface a popup surface">
+ Map the surface as a popup.
+
+ A popup surface is a transient surface with an added pointer
+ grab.
+
+ An existing implicit grab will be changed to owner-events mode,
+ and the popup grab will continue after the implicit grab ends
+ (i.e. releasing the mouse button does not cause the popup to
+ be unmapped).
+
+ The popup grab continues until the window is destroyed or a
+ mouse button is pressed in any other clients window. A click
+ in any of the clients surfaces is reported as normal, however,
+ clicks in other clients surfaces will be discarded and trigger
+ the callback.
+
+ The x and y arguments specify the locations of the upper left
+ corner of the surface relative to the upper left corner of the
+ parent surface, in surface local coordinates.
+ </description>
+
+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
+ <arg name="parent" type="object" interface="wl_surface"/>
+ <arg name="x" type="int"/>
+ <arg name="y" type="int"/>
+ <arg name="flags" type="uint"/>
+ </request>
+
+ <request name="set_maximized">
+ <description summary="make the surface a maximized surface">
+ Map the surface as a maximized surface.
+
+ If an output parameter is given then the surface will be
+ maximized on that output. If the client does not specify the
+ output then the compositor will apply its policy - usually
+ choosing the output on which the surface has the biggest surface
+ area.
+
+ The compositor will reply with a configure event telling
+ the expected new surface size. The operation is completed
+ on the next buffer attach to this surface.
+
+ A maximized surface typically fills the entire output it is
+ bound to, except for desktop element such as panels. This is
+ the main difference between a maximized shell surface and a
+ fullscreen shell surface.
+
+ The details depend on the compositor implementation.
+ </description>
+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
+ </request>
+
+ <request name="set_title">
+ <description summary="set surface title">
+ Set a short title for the surface.
+
+ This string may be used to identify the surface in a task bar,
+ window list, or other user interface elements provided by the
+ compositor.
+
+ The string must be encoded in UTF-8.
+ </description>
+ <arg name="title" type="string"/>
+ </request>
+
+ <request name="set_class">
+ <description summary="set surface class">
+ Set a class for the surface.
+
+ The surface class identifies the general class of applications
+ to which the surface belongs. A common convention is to use
+ the file name (full path if non-standard location) of the
+ applications .desktop file as the class.
+ </description>
+ <arg name="class_" type="string"/>
+ </request>
+
+ <event name="ping">
+ <description summary="ping client">
+ Ping a client to check if it is receiving events and sending
+ requests. A client is expected to reply with a pong request.
+ </description>
+ <arg name="serial" type="uint"/>
+ </event>
+
+ <event name="configure">
+ <description summary="suggest resize">
+ The configure event asks the client to resize its surface.
+
+ The size is a hint, in the sense that the client is free to
+ ignore it if it doesn't resize, pick a smaller size (to
+ satisfy aspect ratio or resize in steps of NxM pixels).
+
+ The edges parameter provides a hint about how the surface
+ was resized. The client may use this information to decide
+ how to adjust its content to the new size (e.g. a scrolling
+ area might adjust its content position to leave the viewable
+ content unmoved).
+
+ The client is free to dismiss all but the last configure
+ event it received.
+
+ The width and height arguments specify the size of the window
+ in surface local coordinates.
+ </description>
+
+ <arg name="edges" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ </event>
+
+ <event name="popup_done">
+ <description summary="popup interaction is done">
+ The popup_done event is sent out when a popup grab is broken,
+ that is, when the users clicks a surface that doesn't belong
+ to the client owning the popup surface.
+ </description>
+ </event>
+ </interface>
+</protocol>
--
1.8.3.1
--
Rafael Antognolli
Pekka Paalanen
2013-10-16 08:33:15 UTC
Permalink
On Tue, 15 Oct 2013 12:17:31 -0300
Post by Rafael Antognolli
Hi Pekka,
I just updated it to cover what you mentioned. The diff from the
http://pastebin.ca/2466952
Hi Rafael,

the diff looks good! :-)


Thanks,
pq
Continue reading on narkive:
Loading...