mirror of
https://github.com/fltk/fltk.git
synced 2026-05-30 21:25:30 +08:00
Wayland: call libdecor_dispatch(), libdecor_unref(), libdecor_get_fd() as expected by libdecor.
Corresponds to these commits to master:8e9e2b7,f121bc1,e8e5e61,d816da5.
This commit is contained in:
@@ -1352,30 +1352,30 @@ static const struct wl_registry_listener registry_listener = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern int fl_send_system_handlers(void *);
|
static void libdecor_fd_callback(int fd, struct libdecor *libdecor_context) {
|
||||||
|
if (libdecor_dispatch(libdecor_context, 0) >= 0) return;
|
||||||
|
if (wl_display_get_error(Fl_Wayland_Screen_Driver::wl_display) == EPROTO) {
|
||||||
static void wayland_socket_callback(int fd, struct wl_display *display) {
|
const struct wl_interface *interface;
|
||||||
if (fl_send_system_handlers(NULL)) return;
|
int code = wl_display_get_protocol_error(Fl_Wayland_Screen_Driver::wl_display, &interface, NULL);
|
||||||
struct pollfd fds = (struct pollfd) { fd, POLLIN, 0 };
|
Fl::fatal("Fatal error no %d in Wayland protocol: %s", code,
|
||||||
do {
|
(interface ? interface->name : "unknown") );
|
||||||
if (wl_display_dispatch(display) == -1) {
|
} else {
|
||||||
int err = wl_display_get_error(display);
|
Fl::fatal("Fatal error while communicating with the Wayland server: %s",
|
||||||
if (err == EPROTO) {
|
strerror(errno));
|
||||||
const struct wl_interface *interface;
|
|
||||||
int code = wl_display_get_protocol_error(display, &interface, NULL);
|
|
||||||
Fl::fatal("Fatal error no %d in Wayland protocol: %s", code,
|
|
||||||
(interface ? interface->name : "unknown") );
|
|
||||||
} else {
|
|
||||||
Fl::fatal("Fatal error while communicating with the Wayland server: %s",
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (poll(&fds, 1, 0) > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_error(struct libdecor *libdecor_context, enum libdecor_error error, const char *message)
|
||||||
|
{
|
||||||
|
Fl::fatal("Caught error (%d): %s\n", error, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct libdecor_interface libdecor_iface = {
|
||||||
|
.error = handle_error,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Unix_Screen_Driver() {
|
Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Unix_Screen_Driver() {
|
||||||
libdecor_context = NULL;
|
libdecor_context = NULL;
|
||||||
seat = NULL;
|
seat = NULL;
|
||||||
@@ -1404,8 +1404,11 @@ static const struct wl_callback_listener sync_listener = {
|
|||||||
|
|
||||||
|
|
||||||
static void do_atexit() {
|
static void do_atexit() {
|
||||||
if (Fl_Wayland_Screen_Driver::wl_display) {
|
// Issue #821 no longer seems to require extra operations under gnome version < 44.
|
||||||
wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display);
|
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
||||||
|
if (scr_driver->libdecor_context) { // libdecor recommends a call to libdecor_unref()
|
||||||
|
libdecor_unref(scr_driver->libdecor_context);
|
||||||
|
scr_driver->libdecor_context = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1431,15 +1434,10 @@ void Fl_Wayland_Screen_Driver::open_display_platform() {
|
|||||||
struct wl_callback *registry_cb = wl_display_sync(wl_display);
|
struct wl_callback *registry_cb = wl_display_sync(wl_display);
|
||||||
wl_callback_add_listener(registry_cb, &sync_listener, ®istry_cb);
|
wl_callback_add_listener(registry_cb, &sync_listener, ®istry_cb);
|
||||||
while (registry_cb) wl_display_dispatch(wl_display);
|
while (registry_cb) wl_display_dispatch(wl_display);
|
||||||
Fl::add_fd(wl_display_get_fd(wl_display), FL_READ, (Fl_FD_Handler)wayland_socket_callback,
|
libdecor_context = libdecor_new(wl_display, &libdecor_iface);
|
||||||
wl_display);
|
Fl::add_fd(libdecor_get_fd(libdecor_context), FL_READ, (Fl_FD_Handler)libdecor_fd_callback,
|
||||||
|
libdecor_context);
|
||||||
fl_create_print_window();
|
fl_create_print_window();
|
||||||
/* This is useful to avoid crash of the Wayland compositor after
|
|
||||||
FLTK apps terminate in certain situations:
|
|
||||||
- gnome-shell version < 44 (e.g. version 42.9)
|
|
||||||
- focus set to "follow-mouse"
|
|
||||||
See issue #821 for details.
|
|
||||||
*/
|
|
||||||
atexit(do_atexit);
|
atexit(do_atexit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1519,21 +1517,20 @@ void Fl_Wayland_Screen_Driver::close_display() {
|
|||||||
wl_seat_destroy(seat->wl_seat); seat->wl_seat = NULL;
|
wl_seat_destroy(seat->wl_seat); seat->wl_seat = NULL;
|
||||||
if (seat->name) free(seat->name);
|
if (seat->name) free(seat->name);
|
||||||
free(seat); seat = NULL;
|
free(seat); seat = NULL;
|
||||||
if (libdecor_context) {
|
|
||||||
libdecor_unref(libdecor_context);
|
|
||||||
libdecor_context = NULL;
|
|
||||||
}
|
|
||||||
xdg_wm_base_destroy(xdg_wm_base); xdg_wm_base = NULL;
|
xdg_wm_base_destroy(xdg_wm_base); xdg_wm_base = NULL;
|
||||||
Fl_Wayland_Plugin *plugin = Fl_Wayland_Window_Driver::gl_plugin();
|
Fl_Wayland_Plugin *plugin = Fl_Wayland_Window_Driver::gl_plugin();
|
||||||
if (plugin) plugin->terminate();
|
if (plugin) plugin->terminate();
|
||||||
|
|
||||||
Fl::remove_fd(wl_display_get_fd(Fl_Wayland_Screen_Driver::wl_display));
|
if (libdecor_context) {
|
||||||
|
Fl::remove_fd(libdecor_get_fd(libdecor_context));
|
||||||
|
libdecor_unref(libdecor_context);
|
||||||
|
libdecor_context = NULL;
|
||||||
|
}
|
||||||
wl_registry_destroy(wl_registry); wl_registry = NULL;
|
wl_registry_destroy(wl_registry); wl_registry = NULL;
|
||||||
wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display);
|
wl_display_disconnect(Fl_Wayland_Screen_Driver::wl_display);
|
||||||
Fl_Wayland_Screen_Driver::wl_display = NULL;
|
Fl_Wayland_Screen_Driver::wl_display = NULL;
|
||||||
delete Fl_Display_Device::display_device()->driver();
|
delete Fl_Display_Device::display_device()->driver();
|
||||||
delete Fl_Display_Device::display_device();
|
delete Fl_Display_Device::display_device();
|
||||||
delete Fl::system_driver();
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -648,17 +648,6 @@ int Fl_Wayland_Window_Driver::scroll(int src_x, int src_y, int src_w, int src_h,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void handle_error(struct libdecor *libdecor_context, enum libdecor_error error, const char *message)
|
|
||||||
{
|
|
||||||
Fl::fatal("Caught error (%d): %s\n", error, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct libdecor_interface libdecor_iface = {
|
|
||||||
.error = handle_error,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void change_scale(Fl_Wayland_Screen_Driver::output *output, struct wld_window *window,
|
void change_scale(Fl_Wayland_Screen_Driver::output *output, struct wld_window *window,
|
||||||
float pre_scale) {
|
float pre_scale) {
|
||||||
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);
|
||||||
@@ -1007,11 +996,12 @@ void Fl_Wayland_Window_Driver::wait_for_expose()
|
|||||||
Fl_Window_Driver::wait_for_expose();
|
Fl_Window_Driver::wait_for_expose();
|
||||||
struct wld_window * xid = fl_wl_xid(pWindow);
|
struct wld_window * xid = fl_wl_xid(pWindow);
|
||||||
if (!xid) return;
|
if (!xid) return;
|
||||||
|
Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver();
|
||||||
if (pWindow->fullscreen_active()) {
|
if (pWindow->fullscreen_active()) {
|
||||||
if (xid->kind == DECORATED) {
|
if (xid->kind == DECORATED) {
|
||||||
while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) ||
|
while (!(xid->state & LIBDECOR_WINDOW_STATE_FULLSCREEN) ||
|
||||||
!(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) {
|
!(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) {
|
||||||
wl_display_dispatch(Fl_Wayland_Screen_Driver::wl_display);
|
libdecor_dispatch(scr_driver->libdecor_context, 0);
|
||||||
}
|
}
|
||||||
} else if (xid->kind == UNFRAMED) {
|
} else if (xid->kind == UNFRAMED) {
|
||||||
wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display);
|
wl_display_roundtrip(Fl_Wayland_Screen_Driver::wl_display);
|
||||||
@@ -1019,7 +1009,7 @@ void Fl_Wayland_Window_Driver::wait_for_expose()
|
|||||||
} else if (xid->kind == DECORATED) {
|
} else if (xid->kind == DECORATED) {
|
||||||
// necessary for the windowfocus demo program with recent Wayland versions
|
// necessary for the windowfocus demo program with recent Wayland versions
|
||||||
if (!(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) {
|
if (!(xid->state & LIBDECOR_WINDOW_STATE_ACTIVE)) {
|
||||||
wl_display_dispatch(Fl_Wayland_Screen_Driver::wl_display);
|
libdecor_dispatch(scr_driver->libdecor_context, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1465,9 +1455,6 @@ void Fl_Wayland_Window_Driver::makeWindow()
|
|||||||
|
|
||||||
} else if (pWindow->border() && !pWindow->parent() ) { // a decorated window
|
} else if (pWindow->border() && !pWindow->parent() ) { // a decorated window
|
||||||
new_window->kind = DECORATED;
|
new_window->kind = DECORATED;
|
||||||
if (!scr_driver->libdecor_context)
|
|
||||||
scr_driver->libdecor_context = libdecor_new(Fl_Wayland_Screen_Driver::wl_display,
|
|
||||||
&libdecor_iface);
|
|
||||||
new_window->frame = libdecor_decorate(scr_driver->libdecor_context, new_window->wl_surface,
|
new_window->frame = libdecor_decorate(scr_driver->libdecor_context, new_window->wl_surface,
|
||||||
&libdecor_frame_iface, new_window);
|
&libdecor_frame_iface, new_window);
|
||||||
// appears in the Gnome desktop menu bar
|
// appears in the Gnome desktop menu bar
|
||||||
|
|||||||
Reference in New Issue
Block a user