mirror of
https://github.com/fltk/fltk.git
synced 2026-05-28 11:25:22 +08:00
Wayland.dox: add info about the xdg decoration protocol
Also, use KWin to name the KDE desktop's Wayland compositor.
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@ the Wayland platform. It requires a Wayland-equipped OS, namely Linux or FreeBSD
|
|||||||
Pre-existing platform-independent source code for FLTK 1.3.x should build and
|
Pre-existing platform-independent source code for FLTK 1.3.x should build and
|
||||||
run unchanged with FLTK 1.4 and the Wayland platform.
|
run unchanged with FLTK 1.4 and the Wayland platform.
|
||||||
The code has been tested on Debian, Ubuntu, RaspberryPiOS and Fedora with
|
The code has been tested on Debian, Ubuntu, RaspberryPiOS and Fedora with
|
||||||
3 distinct Wayland compositors: mutter (Gnome's compositor), weston, and KDE.
|
3 distinct Wayland compositors: Mutter (Gnome's compositor), Weston, and KWin.
|
||||||
The code has also been tested under FreeBSD and the Sway Wayland compositor.
|
The code has also been tested under FreeBSD and the Sway Wayland compositor.
|
||||||
CJK text-input methods, as well as dead and compose keys are supported.
|
CJK text-input methods, as well as dead and compose keys are supported.
|
||||||
|
|
||||||
|
|||||||
@@ -1069,10 +1069,11 @@ or in <tt>$HOME/.local/share/applications/</tt> so it's available to a single us
|
|||||||
\subsection osissues_wayland_decoration Window titlebars
|
\subsection osissues_wayland_decoration Window titlebars
|
||||||
Wayland supports both client-side window decoration (CSD), where client applications
|
Wayland supports both client-side window decoration (CSD), where client applications
|
||||||
are responsible for drawing window titlebars, and server-side window
|
are responsible for drawing window titlebars, and server-side window
|
||||||
decoration (SSD), where the Wayland compositor itself draws window titlebars. Among 3
|
decoration (SSD), where the Wayland compositor itself draws window titlebars. Among 4
|
||||||
tested Wayland compositors, Mutter (gnome's compositor) and Weston use CSD mode
|
tested Wayland compositors, Mutter (gnome's compositor) and Weston use CSD mode
|
||||||
whereas the KDE compositor uses SSD mode. When running in CSD mode, FLTK uses a library called
|
whereas the KWin and Sway compositors use SSD mode.
|
||||||
<a href=https://gitlab.gnome.org/jadahl/libdecor>libdecor</a> to draw titlebars.
|
When running in CSD mode, FLTK uses a library
|
||||||
|
called <a href=https://gitlab.freedesktop.org/libdecor/libdecor>libdecor</a> to draw titlebars.
|
||||||
The libdecor library has been conceived to use various plug-in's to draw
|
The libdecor library has been conceived to use various plug-in's to draw
|
||||||
titlebars in various fashions intended to match any desktop's preferred titlebar style.
|
titlebars in various fashions intended to match any desktop's preferred titlebar style.
|
||||||
FLTK supports drawing titlebars with any libdecor plug-in via an environment variable
|
FLTK supports drawing titlebars with any libdecor plug-in via an environment variable
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ accessible from this object.
|
|||||||
For example, when \c interface equals "wl_compositor", the value returned by
|
For example, when \c interface equals "wl_compositor", the value returned by
|
||||||
\c wl_registry_bind() is stored as member \c wl_compositor of the
|
\c wl_registry_bind() is stored as member \c wl_compositor of the
|
||||||
\c Fl_Wayland_Screen_Driver object.
|
\c Fl_Wayland_Screen_Driver object.
|
||||||
\c registry_handle_global() also identifies whether the Mutter, Weston, or KDE compositor is connected
|
\c registry_handle_global() also identifies whether the Mutter, Weston, or KWin compositor is connected
|
||||||
and stores this information in static member variable \c Fl_Wayland_Screen_Driver::compositor.
|
and stores this information in static member variable \c Fl_Wayland_Screen_Driver::compositor.
|
||||||
|
|
||||||
Wayland calls \c registry_handle_global() with its parameter \c interface equals to
|
Wayland calls \c registry_handle_global() with its parameter \c interface equals to
|
||||||
@@ -726,7 +726,7 @@ is unmapped by function \c Fl_Wayland_Window_Driver::hide(), the surface's list
|
|||||||
is emptied.
|
is emptied.
|
||||||
|
|
||||||
<h3>Fractional scaling</h3>
|
<h3>Fractional scaling</h3>
|
||||||
The KDE compositor, and gnome too if specially set, allow to use <em>fractional scaling</em>
|
The KWin compositor, and gnome too if specially set, allow to use <em>fractional scaling</em>
|
||||||
that can take intermediate values between 100% and 200%. Wayland implements this rendering all
|
that can take intermediate values between 100% and 200%. Wayland implements this rendering all
|
||||||
<tt>wl_surface</tt>'s as if the scaling was at 200%, and downsizing them
|
<tt>wl_surface</tt>'s as if the scaling was at 200%, and downsizing them
|
||||||
to the desired fractional scale value at the compositing stage.
|
to the desired fractional scale value at the compositing stage.
|
||||||
@@ -956,9 +956,16 @@ Desktop. As of early 2023, two titlebar-drawing \c libdecor plugins are availabl
|
|||||||
Because \c libdecor is not yet in Linux packages, or only in a preliminary state, FLTK bundles the
|
Because \c libdecor is not yet in Linux packages, or only in a preliminary state, FLTK bundles the
|
||||||
most recent source code of \c libdecor and its plugins. This code is included in libfltk.
|
most recent source code of \c libdecor and its plugins. This code is included in libfltk.
|
||||||
FLTK uses \c libdecor-gtk when software package \c libgtk-3-dev is present in the
|
FLTK uses \c libdecor-gtk when software package \c libgtk-3-dev is present in the
|
||||||
system, and \c libdecor-cairo otherwise.
|
build system, and \c libdecor-cairo otherwise.
|
||||||
|
|
||||||
\c Libdecor uses the Wayland protocol <tt>"xdg decoration unstable v1"</tt> hinted at before.
|
\c Libdecor uses the Wayland protocol
|
||||||
|
<a href=https://wayland.app/protocols/xdg-decoration-unstable-v1>
|
||||||
|
xdg decoration unstable v1</a> to request being decorated by a supporting compositor.
|
||||||
|
If the running compositor supports SSD, \c libdecor doesn't draw window titlebars because
|
||||||
|
the compositor does it. That is what happens with the \c KWin and \c Sway compositors.
|
||||||
|
However, if environment variable \c LIBDECOR_FORCE_CSD is defined to value \c 1 when an
|
||||||
|
FLTK app runs, \c libdecor instructs an SSD-able compositor to refrain from decorating its
|
||||||
|
windows and decorates windows itself.
|
||||||
|
|
||||||
CMake \c OPTION_USE_SYSTEM_LIBDECOR has been defined to allow FLTK in the future, when \c libdecor and
|
CMake \c OPTION_USE_SYSTEM_LIBDECOR has been defined to allow FLTK in the future, when \c libdecor and
|
||||||
\c libdecor-gtk will be part of Linux packages, to use these packages rather than the \c libdecor
|
\c libdecor-gtk will be part of Linux packages, to use these packages rather than the \c libdecor
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ static unsigned char *cairo_titlebar_buffer(struct libdecor_frame *frame,
|
|||||||
this address.
|
this address.
|
||||||
|
|
||||||
A plugin is loaded also if SSD.
|
A plugin is loaded also if SSD.
|
||||||
KDE has its own size limit, similar to that of GDK plugin
|
KWin has its own size limit, similar to that of GDK plugin
|
||||||
*/
|
*/
|
||||||
static const char *get_libdecor_plugin_description(struct libdecor_frame *frame) {
|
static const char *get_libdecor_plugin_description(struct libdecor_frame *frame) {
|
||||||
static const struct libdecor_plugin_description *plugin_description = NULL;
|
static const struct libdecor_plugin_description *plugin_description = NULL;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ private:
|
|||||||
static bool insertion_point_location_is_valid;
|
static bool insertion_point_location_is_valid;
|
||||||
public:
|
public:
|
||||||
// type definitions
|
// type definitions
|
||||||
typedef enum {unspecified, MUTTER, WESTON, KDE, OWL} compositor_name;
|
typedef enum {unspecified, MUTTER, WESTON, KWIN, OWL} compositor_name;
|
||||||
struct seat {
|
struct seat {
|
||||||
struct wl_seat *wl_seat;
|
struct wl_seat *wl_seat;
|
||||||
struct wl_pointer *wl_pointer;
|
struct wl_pointer *wl_pointer;
|
||||||
|
|||||||
@@ -51,16 +51,16 @@ struct pointer_output {
|
|||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Implementation note about support of 3 Wayland compositors: Mutter, Weston, KDE.
|
/* Implementation note about support of 3 Wayland compositors: Mutter, Weston, KWin.
|
||||||
|
|
||||||
- About CSD and SSD :
|
- About CSD and SSD :
|
||||||
* Mutter and Weston use CSD (client-side decoration) which means that libdecor.so draws all window
|
* Mutter and Weston use CSD (client-side decoration) which means that libdecor.so draws all window
|
||||||
titlebars and responds to resize, minimization and maximization events.
|
titlebars and responds to resize, minimization and maximization events.
|
||||||
* KDE uses SSD (server-side decoration) which means the OS draws titlebars according to its own rules
|
* KWin uses SSD (server-side decoration) which means the OS draws titlebars according to its own rules
|
||||||
and triggers resize, minimization and maximization events.
|
and triggers resize, minimization and maximization events.
|
||||||
|
|
||||||
- Function registry_handle_global() runs within fl_open_display() and sets public static variable
|
- Function registry_handle_global() runs within fl_open_display() and sets public static variable
|
||||||
Fl_Wayland_Screen_Driver::compositor to either Fl_Wayland_Screen_Driver::MUTTER, ::WESTON, or ::KDE.
|
Fl_Wayland_Screen_Driver::compositor to either Fl_Wayland_Screen_Driver::MUTTER, ::WESTON, or ::KWIN.
|
||||||
|
|
||||||
- Specific operations for WESTON:
|
- Specific operations for WESTON:
|
||||||
* When a libdecor-framed window is minimized under Weston, the frame remains on display. To avoid
|
* When a libdecor-framed window is minimized under Weston, the frame remains on display. To avoid
|
||||||
@@ -85,7 +85,7 @@ struct pointer_output {
|
|||||||
|
|
||||||
- Support of Fl_Window::border(int) :
|
- Support of Fl_Window::border(int) :
|
||||||
FLTK uses libdecor_frame_set_visibility() to show or hide a toplevel window's frame. This doesn't work
|
FLTK uses libdecor_frame_set_visibility() to show or hide a toplevel window's frame. This doesn't work
|
||||||
with KDE which uses Server-Side Decoration. In that case, FLTK hides and re-shows the window to toggle
|
with KWin which uses Server-Side Decoration. In that case, FLTK hides and re-shows the window to toggle
|
||||||
between presence and absence of a window's frame.
|
between presence and absence of a window's frame.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1107,8 +1107,8 @@ static void registry_handle_global(void *user_data, struct wl_registry *wl_regis
|
|||||||
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::WESTON;
|
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::WESTON;
|
||||||
//fprintf(stderr, "Running the Weston compositor\n");
|
//fprintf(stderr, "Running the Weston compositor\n");
|
||||||
} else if (strcmp(interface, "org_kde_plasma_shell") == 0) {
|
} else if (strcmp(interface, "org_kde_plasma_shell") == 0) {
|
||||||
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::KDE;
|
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::KWIN;
|
||||||
//fprintf(stderr, "Running the KDE compositor\n");
|
//fprintf(stderr, "Running the KWin compositor\n");
|
||||||
} else if (strncmp(interface, "zowl_mach_ipc", 13) == 0) {
|
} else if (strncmp(interface, "zowl_mach_ipc", 13) == 0) {
|
||||||
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::OWL;
|
Fl_Wayland_Screen_Driver::compositor = Fl_Wayland_Screen_Driver::OWL;
|
||||||
//fprintf(stderr, "Running the Owl compositor\n");
|
//fprintf(stderr, "Running the Owl compositor\n");
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ void Fl_Wayland_Window_Driver::make_current() {
|
|||||||
}
|
}
|
||||||
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(window->buffer, f * wld_s);
|
((Fl_Wayland_Graphics_Driver*)fl_graphics_driver)->set_buffer(window->buffer, f * wld_s);
|
||||||
int *poffset = Fl_Window_Driver::menu_offset_y(pWindow);
|
int *poffset = Fl_Window_Driver::menu_offset_y(pWindow);
|
||||||
if (poffset) { // for tall menu windows under KDE to offset drawing inside window
|
if (poffset) { // for tall menu windows under KWIN to offset drawing inside window
|
||||||
cairo_translate(window->buffer->cairo_, 0, *poffset);
|
cairo_translate(window->buffer->cairo_, 0, *poffset);
|
||||||
}
|
}
|
||||||
cairo_rectangle_int_t *extents = subRect();
|
cairo_rectangle_int_t *extents = subRect();
|
||||||
@@ -799,7 +799,7 @@ static void handle_configure(struct libdecor_frame *frame,
|
|||||||
}
|
}
|
||||||
window->state = window_state;
|
window->state = window_state;
|
||||||
|
|
||||||
// Weston, KDE, and some versions of Mutter, on purpose, don't set the
|
// Weston, KWin, and some versions of Mutter, on purpose, don't set the
|
||||||
// window width x height when xdg_toplevel_configure runs twice
|
// window width x height when xdg_toplevel_configure runs twice
|
||||||
// during resizable window creation (see https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/6).
|
// during resizable window creation (see https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/6).
|
||||||
// Consequently, libdecor_configuration_get_content_size() may return false twice.
|
// Consequently, libdecor_configuration_get_content_size() may return false twice.
|
||||||
@@ -1037,7 +1037,7 @@ static void popup_configure(void *data, struct xdg_popup *xdg_popup, int32_t x,
|
|||||||
int HH;
|
int HH;
|
||||||
Fl_Window_Driver::menu_parent(&HH);
|
Fl_Window_Driver::menu_parent(&HH);
|
||||||
if (window->fl_win->h() > HH && y != win_pos->y) { // A menu taller than the display
|
if (window->fl_win->h() > HH && y != win_pos->y) { // A menu taller than the display
|
||||||
// Under KDE, height is set to the display height or less: we ignore that.
|
// Under KWin, height is set to the display height or less: we ignore that.
|
||||||
window->state = (y - win_pos->y);
|
window->state = (y - win_pos->y);
|
||||||
// make selected item visible, if there's one
|
// make selected item visible, if there's one
|
||||||
Fl_Window_Driver::scroll_to_selected_item(window->fl_win);
|
Fl_Window_Driver::scroll_to_selected_item(window->fl_win);
|
||||||
@@ -1551,7 +1551,7 @@ void Fl_Wayland_Window_Driver::use_border() {
|
|||||||
if (!shown() || pWindow->parent()) return;
|
if (!shown() || pWindow->parent()) return;
|
||||||
pWindow->wait_for_expose(); // useful for border(0) just after show()
|
pWindow->wait_for_expose(); // useful for border(0) just after show()
|
||||||
struct libdecor_frame *frame = fl_wl_xid(pWindow)->frame;
|
struct libdecor_frame *frame = fl_wl_xid(pWindow)->frame;
|
||||||
if (frame && Fl_Wayland_Screen_Driver::compositor != Fl_Wayland_Screen_Driver::KDE) {
|
if (frame && Fl_Wayland_Screen_Driver::compositor != Fl_Wayland_Screen_Driver::KWIN) {
|
||||||
if (fl_wl_xid(pWindow)->kind == DECORATED) {
|
if (fl_wl_xid(pWindow)->kind == DECORATED) {
|
||||||
libdecor_frame_set_visibility(frame, pWindow->border());
|
libdecor_frame_set_visibility(frame, pWindow->border());
|
||||||
} else {
|
} else {
|
||||||
@@ -1832,8 +1832,8 @@ void Fl_Wayland_Window_Driver::subRect(cairo_rectangle_int_t *r) {
|
|||||||
|
|
||||||
void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) {
|
void Fl_Wayland_Window_Driver::reposition_menu_window(int x, int y) {
|
||||||
if (y == pWindow->y()) return;
|
if (y == pWindow->y()) return;
|
||||||
if (Fl_Wayland_Screen_Driver::compositor == Fl_Wayland_Screen_Driver::KDE) {
|
if (Fl_Wayland_Screen_Driver::compositor == Fl_Wayland_Screen_Driver::KWIN) {
|
||||||
// The KDE compositor refuses to position a popup such that it extends above
|
// The KWin compositor refuses to position a popup such that it extends above
|
||||||
// the top of the screen. Therefore, instead of sliding the popup window
|
// the top of the screen. Therefore, instead of sliding the popup window
|
||||||
// on the display, we slide the drawing inside the fixed popup via
|
// on the display, we slide the drawing inside the fixed popup via
|
||||||
// member variable offset_y of the menuwindow class, and we redraw the popup
|
// member variable offset_y of the menuwindow class, and we redraw the popup
|
||||||
|
|||||||
Reference in New Issue
Block a user