Wayland: improve and document support of FL_CURSOR_NONE

This commit is contained in:
ManoloFLTK 2023-02-17 09:52:22 +01:00
parent 89874f4f85
commit e84a1730ad
3 changed files with 34 additions and 31 deletions

View File

@ -436,27 +436,31 @@ installed by a call to function \c wl_seat_add_listener() made by function
\section wayland-cursor Wayland cursors
Wayland defines types <tt>struct wl_cursor</tt> and <tt>struct wl_cursor_theme</tt> to hold
cursor-related data. FLTK stores in member variable
\c default_cursor of the \ref seat record, a pointer to the currently used cursor.
Function \c Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor) calls \c wl_cursor_theme_get_cursor()
to set the current cursor shape to one of the standard shapes from the \c Fl_Cursor enumeration.
This Wayland function selects a cursor shape based on the current 'cursor theme' and a cursor name.
Cursor names are the files of directory \c /usr/share/icons/XXXX/cursors/ where \c XXXX is the name of
the 'cursor theme'. For example, what FLTK calls \c FL_CURSOR_INSERT corresponds to file \c xterm
therein. The full correspondance between \c Fl_Cursor values and Wayland cursor names is found
in function \c Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor).
FLTK uses function \c init_cursors() from file \c Fl_Wayland_Screen_Driver.cxx to identify the
app's 'cursor theme' using function \c libdecor_get_cursor_settings() of library \c libdecor,
and to store it in member variable \c cursor_theme of the \ref seat record.
cursor-related data.
FLTK uses function \c init_cursors() from file \c Fl_Wayland_Screen_Driver.cxx to obtain the
'cursor theme' name using function \c libdecor_get_cursor_settings() of library \c libdecor.
Function \c wl_cursor_theme_load() then returns a pointer to an object of type
<tt>struct wl_cursor_theme</tt> stored in member variable \c cursor_theme of the \ref seat record.
Function \c init_cursors() is itself called by a 'listener' called \c seat_capabilities()
installed when function \c registry_handle_global() receives a \c "wl_seat" interface, at program
startup. It is also called when the value of the Wayland scaling factor changes:
\c output_done() calls \c try_update_cursor() calls \c init_cursors().
\c output_done() calls \c try_update_cursor() calls \c init_cursors(). Function \c output_done()
belongs to a 'listener' installed when function \c registry_handle_global() receives a
\c "wl_output" interface.
Each time member function \c Fl_Window::cursor(Fl_Cursor) runs, FLTK calls
\c Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor) which stores the desired cursor shape in
member \c standard_cursor_ of the \c Fl_Wayland_Window_Driver object.
Each time \c Fl_Window::cursor(Fl_Cursor) runs, FLTK calls
\c Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor) which calls \c wl_cursor_theme_get_cursor()
to set the current cursor shape to one of the standard shapes from the \c Fl_Cursor enumeration.
This Wayland function selects a cursor shape based on the current \c wl_cursor_theme object
and a cursor name and returns a pointer to a <tt>struct wl_cursor</tt>.
Under the gnome desktop, cursor names are the files of directory \c /usr/share/icons/XXXX/cursors/
where \c XXXX is the 'gnome cursor theme' (default= Adwaita). For example, what FLTK calls
\c FL_CURSOR_INSERT corresponds to file \c xterm therein. The full correspondance between
\c Fl_Cursor values and names of files therein is found in function
\c Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor). FLTK stores in member variable
\c default_cursor of the \ref seat record, a pointer to the currently used \c wl_cursor object,
and the current \c Fl_Cursor value in member \c standard_cursor_ of the \c Fl_Wayland_Window_Driver
object.
Function <tt>Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int hoty)</tt>
is used to create a custom cursor shape. This operation is relatively complex, specially because
@ -467,6 +471,13 @@ is stored in member \c custom_cursor of the window's \ref wld_window. Member fun
occurs when a window associated to a custom cursor is un-mapped and when such a window gets
associated to a standard cursor or to a new custom cursor.
The \c FL_CURSOR_NONE cursor shape is normally implemented by FLTK as a custom cursor shape in
function \c fallback_cursor() of file \c src/fl_cursor.cxx. Because both FLTK classes \c Fl_Input and
\c Fl_Text_Editor often use \c FL_CURSOR_NONE, FLTK's Wayland backend uses an additional piece of
code to avoid the construction of a new \c wl_cursor object each time \c FL_CURSOR_NONE is set:
function \c Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor) creates a null-shaped \c wl_cursor
object the first time it's called with argument \c FL_CURSOR_NONE and stores it in member \c xc_none
of the \c Fl_Wayland_Screen_Driver object, allowing later re-use of this cursor object.
\section wayland-text Text input

View File

@ -1450,7 +1450,9 @@ struct wl_cursor *Fl_Wayland_Screen_Driver::cache_cursor(const char *cursor_name
}
void Fl_Wayland_Screen_Driver::reset_cursor() {
xc_arrow = xc_ns = xc_wait = xc_insert = xc_hand = xc_help = xc_cross = xc_move = xc_north = xc_south = xc_west = xc_east = xc_we = xc_nesw = xc_nwse = xc_sw = xc_se = xc_ne = xc_nw = NULL;
xc_arrow = xc_ns = xc_wait = xc_insert = xc_hand = xc_help = xc_cross = xc_move =
xc_north = xc_south = xc_west = xc_east = xc_we = xc_nesw = xc_nwse = xc_sw = xc_se =
xc_ne = xc_nw = xc_none = NULL;
}
uint32_t Fl_Wayland_Screen_Driver::get_serial() {

View File

@ -22,8 +22,6 @@
#include <FL/filename.H>
#include <wayland-cursor.h>
#include "../../../libdecor/src/libdecor.h"
#include "../../fl_cursor_none.xpm"
#include "../../fl_cursor_help.xpm"
#include "xdg-shell-client-protocol.h"
#include <pango/pangocairo.h>
#include <FL/Fl_Overlay_Window.H>
@ -1341,14 +1339,7 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) {
break;
case FL_CURSOR_HELP:
if (!scr_driver->xc_help) scr_driver->xc_help = scr_driver->cache_cursor("help");
if (!scr_driver->xc_help) {
const char **xpm = (const char**)fl_cursor_help_xpm;
Fl_Pixmap pxm(xpm);
Fl_RGB_Image image(&pxm);
this->set_cursor(&image, 1, 3);
scr_driver->xc_help = xid->custom_cursor;
xid->custom_cursor = NULL;
}
if (!scr_driver->xc_help) return 0;
scr_driver->default_cursor(scr_driver->xc_help);
break;
case FL_CURSOR_MOVE:
@ -1413,9 +1404,8 @@ int Fl_Wayland_Window_Driver::set_cursor(Fl_Cursor c) {
break;
case FL_CURSOR_NONE:
if (!scr_driver->xc_none) {
const char **xpm = (const char**)fl_cursor_none_xpm;
Fl_Pixmap pxm(xpm);
Fl_RGB_Image image(&pxm);
static const uchar pixel[] = {0, 0, 0, 0};
Fl_RGB_Image image(pixel, 1, 1, 4);
this->set_cursor(&image, 0, 0);
scr_driver->xc_none = xid->custom_cursor;
xid->custom_cursor = NULL;