Wayland: add support for multiple high or low DPI displays
This commit is contained in:
parent
af4789077f
commit
eeb9267e6e
@ -526,17 +526,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void make_current();
|
void make_current();
|
||||||
|
|
||||||
/**
|
|
||||||
Changes the cursor for this window.
|
|
||||||
|
|
||||||
This always calls the system. If you are changing the cursor a lot
|
|
||||||
you may want to keep track of how you set it in a static variable
|
|
||||||
and call this only if the new cursor is different.
|
|
||||||
|
|
||||||
The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
|
|
||||||
|
|
||||||
\see cursor(const Fl_RGB_Image*, int, int), default_cursor()
|
|
||||||
*/
|
|
||||||
void cursor(Fl_Cursor);
|
void cursor(Fl_Cursor);
|
||||||
void cursor(const Fl_RGB_Image*, int, int);
|
void cursor(const Fl_RGB_Image*, int, int);
|
||||||
void default_cursor(Fl_Cursor);
|
void default_cursor(Fl_Cursor);
|
||||||
|
|||||||
@ -96,12 +96,9 @@ a minimized window has no effect.
|
|||||||
it's currently not possible for an app to be notified of changes to the content of
|
it's currently not possible for an app to be notified of changes to the content of
|
||||||
the system clipboard, that is, Fl::add_clipboard_notify() has no effect.
|
the system clipboard, that is, Fl::add_clipboard_notify() has no effect.
|
||||||
|
|
||||||
* With GTK-style window titlebars, narrow windows are silently forced to be wide enough
|
* Narrow windows with a titlebar are silently forced to be wide enough
|
||||||
for the titlebar to display window buttons and a few letters of the title.
|
for the titlebar to display window buttons and a few letters of the title.
|
||||||
|
|
||||||
* The library should support multi-display configurations in principle, but has not been
|
|
||||||
tested in that situation.
|
|
||||||
|
|
||||||
* Text input methods have been tested without any understanding of the writing systems,
|
* Text input methods have been tested without any understanding of the writing systems,
|
||||||
so feedback on this subject would be helpful.
|
so feedback on this subject would be helpful.
|
||||||
|
|
||||||
|
|||||||
@ -451,19 +451,19 @@ displaying dragged text in a DnD operation.
|
|||||||
|
|
||||||
\section wayland-display Displays and HighDPI support
|
\section wayland-display Displays and HighDPI support
|
||||||
|
|
||||||
Wayland uses the concept of seat of type <tt>struct wl_seat</tt> which encompasses displays,
|
Wayland uses the concept of <em>seat</em> of type <tt>struct wl_seat</tt> which encompasses displays,
|
||||||
a keyboard, a mouse, and a trackpad. It might be possible for an app to deal with several seats,
|
a keyboard, a mouse, and a trackpad. Although Wayland may be in principle able to deal with several
|
||||||
but that has not been tested with FLTK yet. Each seat may contain one or more displays, which
|
seats, FLTK's Wayland platform is conceived for one seat only. That seat may contain one or more
|
||||||
Wayland calls outputs, of type <tt>struct wl_output</tt>.
|
displays, which Wayland calls <em>outputs</em>, of type <tt>struct wl_output</tt>.
|
||||||
|
|
||||||
As written above, function \c registry_handle_global() discovers available seats at start-up time.
|
As written above, function \c registry_handle_global() discovers the available seat at start-up time.
|
||||||
This function also associates a 'listener' to each display
|
This function also associates a listener to each display connected to the system
|
||||||
by calling function \c wl_output_add_listener(). This 'listener' is an array of callback function
|
by calling function \c wl_output_add_listener(). This listener is an array of callback function
|
||||||
pointers among which one (\c output_mode) runs when the display is resized and another
|
pointers among which one (\c output_mode) runs when the display is resized and another
|
||||||
(\c output_scale) when the Wayland scale factor (see below) is changed.
|
(\c output_scale) when the Wayland scale factor (see below) is changed.
|
||||||
FLTK defines type <tt>struct Fl_Wayland_Screen_Driver::output</tt> (see \ref output)
|
FLTK defines type <tt>struct Fl_Wayland_Screen_Driver::output</tt> (see \ref output)
|
||||||
to store display size and scaling information.
|
to store display size and scaling information.
|
||||||
One such record is created for each display. FLTK uses 2 distinct scaling parameters under Wayland:
|
One such record is created for each display. FLTK uses 2 distinct scaling parameters for each display:
|
||||||
- <tt>int wld_scale;</tt>. This member variable of
|
- <tt>int wld_scale;</tt>. This member variable of
|
||||||
<tt>struct Fl_Wayland_Screen_Driver::output</tt> typically equals 1 for standard, and 2 for
|
<tt>struct Fl_Wayland_Screen_Driver::output</tt> typically equals 1 for standard, and 2 for
|
||||||
HighDPI displays. Its value is set by the Wayland compositor for each display with the effect
|
HighDPI displays. Its value is set by the Wayland compositor for each display with the effect
|
||||||
|
|||||||
@ -179,7 +179,6 @@ static void do_set_cursor(struct seat *seat, struct wl_cursor *wl_cursor = NULL)
|
|||||||
image->hotspot_x / scale,
|
image->hotspot_x / scale,
|
||||||
image->hotspot_y / scale);
|
image->hotspot_y / scale);
|
||||||
wl_surface_attach(seat->cursor_surface, buffer, 0, 0);
|
wl_surface_attach(seat->cursor_surface, buffer, 0, 0);
|
||||||
wl_surface_set_buffer_scale(seat->cursor_surface, scale);
|
|
||||||
wl_surface_damage_buffer(seat->cursor_surface, 0, 0,
|
wl_surface_damage_buffer(seat->cursor_surface, 0, 0,
|
||||||
image->width, image->height);
|
image->width, image->height);
|
||||||
wl_surface_commit(seat->cursor_surface);
|
wl_surface_commit(seat->cursor_surface);
|
||||||
@ -258,7 +257,8 @@ static void pointer_enter(void *data,
|
|||||||
{
|
{
|
||||||
Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y);
|
Fl_Window *win = event_coords_from_surface(surface, surface_x, surface_y);
|
||||||
if (!win) return;
|
if (!win) return;
|
||||||
struct wl_cursor *cursor = fl_wl_xid(win)->custom_cursor;// use custom cursor if present
|
// use custom cursor if present
|
||||||
|
struct wl_cursor *cursor = fl_wl_xid(win)->custom_cursor ? fl_wl_xid(win)->custom_cursor->wl_cursor : NULL;
|
||||||
struct seat *seat = (struct seat*)data;
|
struct seat *seat = (struct seat*)data;
|
||||||
do_set_cursor(seat, cursor);
|
do_set_cursor(seat, cursor);
|
||||||
seat->serial = serial;
|
seat->serial = serial;
|
||||||
@ -412,6 +412,7 @@ static void cursor_surface_enter(void *data,
|
|||||||
struct wl_surface *wl_surface,
|
struct wl_surface *wl_surface,
|
||||||
struct wl_output *wl_output)
|
struct wl_output *wl_output)
|
||||||
{
|
{
|
||||||
|
// Runs when the seat's cursor_surface enters a display
|
||||||
struct seat *seat = (struct seat*)data;
|
struct seat *seat = (struct seat*)data;
|
||||||
struct pointer_output *pointer_output;
|
struct pointer_output *pointer_output;
|
||||||
|
|
||||||
@ -428,9 +429,13 @@ static void cursor_surface_enter(void *data,
|
|||||||
if (win) {
|
if (win) {
|
||||||
Fl_Wayland_Window_Driver *driver = Fl_Wayland_Window_Driver::driver(win);
|
Fl_Wayland_Window_Driver *driver = Fl_Wayland_Window_Driver::driver(win);
|
||||||
//fprintf(stderr, "cursor_surface_enter: cursor_default=%d standard_cursor=%d\n", driver->cursor_default(), driver->standard_cursor());
|
//fprintf(stderr, "cursor_surface_enter: cursor_default=%d standard_cursor=%d\n", driver->cursor_default(), driver->standard_cursor());
|
||||||
struct wl_cursor *cursor = fl_wl_xid(win)->custom_cursor;
|
struct wld_window *xid = fl_wl_xid(win);
|
||||||
if (cursor) do_set_cursor(seat, cursor);
|
struct wld_window::custom_cursor *custom = xid->custom_cursor;
|
||||||
else if (driver->cursor_default()) driver->set_cursor(driver->cursor_default());
|
if (custom) {
|
||||||
|
// Change custom cursor's width & height according to display's wld_scale
|
||||||
|
driver->set_cursor_4args(custom->rgb, custom->hotx, custom->hoty, false);
|
||||||
|
do_set_cursor(seat, xid->custom_cursor->wl_cursor);
|
||||||
|
} else if (driver->cursor_default()) driver->set_cursor(driver->cursor_default());
|
||||||
else win->cursor(driver->standard_cursor());
|
else win->cursor(driver->standard_cursor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -448,6 +453,14 @@ static void cursor_surface_leave(void *data,
|
|||||||
free(pointer_output);
|
free(pointer_output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try_update_cursor(seat);
|
||||||
|
// maintain custom window cursor
|
||||||
|
Fl_Window *win = Fl::first_window();
|
||||||
|
if (win) {
|
||||||
|
struct wld_window *xid = fl_wl_xid(win);
|
||||||
|
if (xid->custom_cursor) do_set_cursor(seat, xid->custom_cursor->wl_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wl_surface_listener cursor_surface_listener = {
|
static struct wl_surface_listener cursor_surface_listener = {
|
||||||
@ -962,6 +975,17 @@ static void output_scale(void *data, struct wl_output *wl_output, int32_t factor
|
|||||||
Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)data;
|
Fl_Wayland_Screen_Driver::output *output = (Fl_Wayland_Screen_Driver::output*)data;
|
||||||
output->wld_scale = factor;
|
output->wld_scale = factor;
|
||||||
//fprintf(stderr,"output_scale: wl_output=%p factor=%d\n",wl_output, factor);
|
//fprintf(stderr,"output_scale: wl_output=%p factor=%d\n",wl_output, factor);
|
||||||
|
// rescale cursors of windows that map here and have a custom cursor
|
||||||
|
Fl_Window *win = Fl::first_window();
|
||||||
|
while (win) {
|
||||||
|
struct wld_window *xid = fl_wl_xid(win);
|
||||||
|
if (xid->custom_cursor && wl_output_get_user_data(wl_output) == xid->output) {
|
||||||
|
Fl_Wayland_Window_Driver *driver = Fl_Wayland_Window_Driver::driver(win);
|
||||||
|
driver->set_cursor_4args(xid->custom_cursor->rgb,
|
||||||
|
xid->custom_cursor->hotx, xid->custom_cursor->hoty, false);
|
||||||
|
};
|
||||||
|
win = Fl::next_window(win);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -60,7 +60,7 @@ private:
|
|||||||
static bool in_flush; // useful for progressive window drawing
|
static bool in_flush; // useful for progressive window drawing
|
||||||
static Fl_Wayland_Plugin *gl_plugin();
|
static Fl_Wayland_Plugin *gl_plugin();
|
||||||
Fl_Cursor standard_cursor_; // window's standard custom kind
|
Fl_Cursor standard_cursor_; // window's standard custom kind
|
||||||
void delete_cursor_(struct wld_window *);
|
void delete_cursor_(struct wld_window *, bool keep_rgb = false);
|
||||||
struct gl_start_support *gl_start_support_; // for support of gl_start/gl_finish
|
struct gl_start_support *gl_start_support_; // for support of gl_start/gl_finish
|
||||||
public:
|
public:
|
||||||
inline Fl_Cursor standard_cursor() { return standard_cursor_; };
|
inline Fl_Cursor standard_cursor() { return standard_cursor_; };
|
||||||
@ -116,6 +116,7 @@ public:
|
|||||||
// --- window cursor stuff
|
// --- window cursor stuff
|
||||||
int set_cursor(Fl_Cursor) FL_OVERRIDE;
|
int set_cursor(Fl_Cursor) FL_OVERRIDE;
|
||||||
int set_cursor(const Fl_RGB_Image*, int, int) FL_OVERRIDE;
|
int set_cursor(const Fl_RGB_Image*, int, int) FL_OVERRIDE;
|
||||||
|
int set_cursor_4args(const Fl_RGB_Image*, int, int, bool);
|
||||||
|
|
||||||
void shape(const Fl_Image* img) FL_OVERRIDE;
|
void shape(const Fl_Image* img) FL_OVERRIDE;
|
||||||
void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE;
|
void capture_titlebar_and_borders(Fl_RGB_Image*& top, Fl_RGB_Image*& left, Fl_RGB_Image*& bottom, Fl_RGB_Image*& right) FL_OVERRIDE;
|
||||||
@ -136,14 +137,18 @@ struct wld_window {
|
|||||||
struct wl_surface *wl_surface;
|
struct wl_surface *wl_surface;
|
||||||
struct fl_wld_buffer *buffer;
|
struct fl_wld_buffer *buffer;
|
||||||
struct xdg_surface *xdg_surface;
|
struct xdg_surface *xdg_surface;
|
||||||
union {
|
enum Fl_Wayland_Window_Driver::kind kind;
|
||||||
|
union { // for each value of kind
|
||||||
struct libdecor_frame *frame;
|
struct libdecor_frame *frame;
|
||||||
struct wl_subsurface *subsurface;
|
struct wl_subsurface *subsurface;
|
||||||
struct xdg_popup *xdg_popup;
|
struct xdg_popup *xdg_popup;
|
||||||
struct xdg_toplevel *xdg_toplevel;
|
struct xdg_toplevel *xdg_toplevel;
|
||||||
};
|
};
|
||||||
struct wl_cursor *custom_cursor; // non-null when using custom cursor
|
struct custom_cursor {
|
||||||
enum Fl_Wayland_Window_Driver::kind kind;
|
struct wl_cursor *wl_cursor;
|
||||||
|
const Fl_RGB_Image *rgb;
|
||||||
|
int hotx, hoty;
|
||||||
|
} *custom_cursor; // non-null when using custom cursor
|
||||||
int configured_width;
|
int configured_width;
|
||||||
int configured_height;
|
int configured_height;
|
||||||
int floating_width;
|
int floating_width;
|
||||||
|
|||||||
@ -78,9 +78,10 @@ Fl_Wayland_Window_Driver::Fl_Wayland_Window_Driver(Fl_Window *win) : Fl_Window_D
|
|||||||
subRect_ = NULL;
|
subRect_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fl_Wayland_Window_Driver::delete_cursor_(struct wld_window *xid) {
|
void Fl_Wayland_Window_Driver::delete_cursor_(struct wld_window *xid, bool keep_rgb) {
|
||||||
struct wl_cursor *wl_cursor = xid->custom_cursor;
|
struct wld_window::custom_cursor *custom = xid->custom_cursor;
|
||||||
if (wl_cursor) {
|
if (custom) {
|
||||||
|
struct wl_cursor *wl_cursor = custom->wl_cursor;
|
||||||
struct cursor_image *new_image = (struct cursor_image*)wl_cursor->images[0];
|
struct cursor_image *new_image = (struct cursor_image*)wl_cursor->images[0];
|
||||||
struct fl_wld_buffer *offscreen = (struct fl_wld_buffer *)wl_buffer_get_user_data(new_image->buffer);
|
struct fl_wld_buffer *offscreen = (struct fl_wld_buffer *)wl_buffer_get_user_data(new_image->buffer);
|
||||||
struct wld_window fake_xid;
|
struct wld_window fake_xid;
|
||||||
@ -92,6 +93,8 @@ void Fl_Wayland_Window_Driver::delete_cursor_(struct wld_window *xid) {
|
|||||||
free(wl_cursor);
|
free(wl_cursor);
|
||||||
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
||||||
if (scr_driver->default_cursor() == wl_cursor) scr_driver->default_cursor(scr_driver->xc_arrow);
|
if (scr_driver->default_cursor() == wl_cursor) scr_driver->default_cursor(scr_driver->xc_arrow);
|
||||||
|
if (!keep_rgb) delete custom->rgb;
|
||||||
|
delete custom;
|
||||||
xid->custom_cursor = NULL;
|
xid->custom_cursor = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -637,6 +640,7 @@ static void surface_enter(void *data, struct wl_surface *wl_surface, struct wl_o
|
|||||||
if (output == NULL)
|
if (output == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//printf("surface_enter win=%p wl_output=%p wld_scale=%d\n", window->fl_win, wl_output, output->wld_scale);
|
||||||
window->output = output;
|
window->output = output;
|
||||||
Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(window->fl_win);
|
Fl_Wayland_Window_Driver *win_driver = Fl_Wayland_Window_Driver::driver(window->fl_win);
|
||||||
if (!window->fl_win->parent()) { // for top-level, set its screen number
|
if (!window->fl_win->parent()) { // for top-level, set its screen number
|
||||||
@ -652,15 +656,23 @@ static void surface_enter(void *data, struct wl_surface *wl_surface, struct wl_o
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (window->kind == Fl_Wayland_Window_Driver::POPUP) {
|
||||||
|
Fl_Wayland_Graphics_Driver::buffer_release(window);
|
||||||
|
window->fl_win->redraw();
|
||||||
|
} else {
|
||||||
|
win_driver->is_a_rescale(true);
|
||||||
|
window->fl_win->size(window->fl_win->w(), window->fl_win->h());
|
||||||
|
win_driver->is_a_rescale(false);
|
||||||
|
if (window->fl_win->as_gl_window())
|
||||||
|
wl_surface_set_buffer_scale(window->wl_surface, output->wld_scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output)
|
static void surface_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output)
|
||||||
{
|
{
|
||||||
struct wld_window *window = (struct wld_window*)data;
|
// Do nothing because surface_leave old display arrives **after** surface_enter new display
|
||||||
if (! window->wl_surface) return;
|
//struct wld_window *window = (struct wld_window*)data;
|
||||||
if (window->output->wl_output == wl_output) {
|
//printf("surface_leave win=%p wl_output=%p\n", window->fl_win, wl_output);
|
||||||
window->output = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wl_surface_listener surface_listener = {
|
static struct wl_surface_listener surface_listener = {
|
||||||
@ -1453,6 +1465,21 @@ void Fl_Wayland_Window_Driver::label(const char *name, const char *iname) {
|
|||||||
|
|
||||||
|
|
||||||
int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int hoty) {
|
int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int hoty) {
|
||||||
|
return set_cursor_4args(rgb, hotx, hoty, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Fl_Wayland_Window_Driver::set_cursor_4args(const Fl_RGB_Image *rgb, int hotx, int hoty,
|
||||||
|
bool keep_copy) {
|
||||||
|
if (keep_copy) {
|
||||||
|
int ld = rgb->ld() ? rgb->ld() : rgb->data_w() * rgb->d();
|
||||||
|
uchar *data = new uchar[ld * rgb->data_h()];
|
||||||
|
memcpy(data, rgb->array, ld * rgb->data_h());
|
||||||
|
Fl_RGB_Image *rgb2 = new Fl_RGB_Image(data, rgb->data_w(), rgb->data_h(), rgb->d(), rgb->ld());
|
||||||
|
rgb2->alloc_array = 1;
|
||||||
|
rgb2->scale(rgb->w(), rgb->h());
|
||||||
|
rgb = rgb2;
|
||||||
|
}
|
||||||
// build a new wl_cursor and its image
|
// build a new wl_cursor and its image
|
||||||
struct wld_window *xid = (struct wld_window *)Fl_Window_Driver::xid(pWindow);
|
struct wld_window *xid = (struct wld_window *)Fl_Window_Driver::xid(pWindow);
|
||||||
struct wl_cursor *new_cursor = (struct wl_cursor*)malloc(sizeof(struct wl_cursor));
|
struct wl_cursor *new_cursor = (struct wl_cursor*)malloc(sizeof(struct wl_cursor));
|
||||||
@ -1482,12 +1509,15 @@ int Fl_Wayland_Window_Driver::set_cursor(const Fl_RGB_Image *rgb, int hotx, int
|
|||||||
Fl_Surface_Device::pop_current();
|
Fl_Surface_Device::pop_current();
|
||||||
delete img_surf;
|
delete img_surf;
|
||||||
memcpy(offscreen->data, offscreen->draw_buffer, offscreen->data_size);
|
memcpy(offscreen->data, offscreen->draw_buffer, offscreen->data_size);
|
||||||
// delete the previous custom cursor, if there was one
|
// delete the previous custom cursor, if there was one, but keep its Fl_RGB_Image
|
||||||
delete_cursor_(xid);
|
delete_cursor_(xid, true);
|
||||||
//have this new cursor used
|
//have this new cursor used
|
||||||
xid->custom_cursor = new_cursor;
|
xid->custom_cursor = new struct wld_window::custom_cursor;
|
||||||
|
xid->custom_cursor->wl_cursor = new_cursor;
|
||||||
|
xid->custom_cursor->rgb = rgb;
|
||||||
|
xid->custom_cursor->hotx = hotx;
|
||||||
|
xid->custom_cursor->hoty = hoty;
|
||||||
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
||||||
scr_driver->default_cursor(xid->custom_cursor);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,6 +107,18 @@ static void fallback_cursor(Fl_Window *w, Fl_Cursor c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Changes the cursor for this window.
|
||||||
|
|
||||||
|
The window must be show()'n for this function to have any effect.
|
||||||
|
This always calls the system. If you are changing the cursor a lot
|
||||||
|
you may want to keep track of how you set it in a static variable
|
||||||
|
and call this only if the new cursor is different.
|
||||||
|
|
||||||
|
The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
|
||||||
|
|
||||||
|
\see cursor(const Fl_RGB_Image*, int, int), default_cursor()
|
||||||
|
*/
|
||||||
void Fl_Window::cursor(Fl_Cursor c) {
|
void Fl_Window::cursor(Fl_Cursor c) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -137,13 +149,17 @@ void Fl_Window::cursor(Fl_Cursor c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Changes the cursor for this window. This always calls the system. If
|
Changes the cursor for this window using the provided image as cursor's shape.
|
||||||
|
The window must be show()'n for this function to have any effect.
|
||||||
|
This always calls the system. If
|
||||||
you are changing the cursor a lot you may want to keep track of how
|
you are changing the cursor a lot you may want to keep track of how
|
||||||
you set it in a static variable and call this only if the new cursor
|
you set it in a static variable and call this only if the new cursor
|
||||||
is different.
|
is different.
|
||||||
|
|
||||||
The default cursor will be used if the provided image cannot be used
|
The default cursor will be used if the provided image cannot be used
|
||||||
as a cursor.
|
as a cursor.
|
||||||
|
\param image Sets the cursor size and shape
|
||||||
|
\param hotx,hoty Sets the cursor's active location relatively to top-left of \c image when clicking
|
||||||
|
|
||||||
\see cursor(Fl_Cursor), default_cursor()
|
\see cursor(Fl_Cursor), default_cursor()
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user