1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
//
// Interface with the libdecor library for the Fast Light Tool Kit (FLTK).
//
// Copyright 2022 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
/* Improvements to libdecor.c without modifying libdecor.c itself */
// this part to support libdecor commit f43652c7 dated 15-jul-2023
#include "xdg-shell-client-protocol.h"
#ifndef XDG_TOPLEVEL_STATE_SUSPENDED_SINCE_VERSION
# define XDG_TOPLEVEL_STATE_SUSPENDED (enum xdg_toplevel_state)9
#endif
// end of this part
#define libdecor_frame_set_minimized libdecor_frame_set_minimized_orig
#define libdecor_new libdecor_new_orig
#include <dlfcn.h>
static void *dlopen_corrected(const char *, int);
#define dlopen(A, B) dlopen_corrected(A, B)
#include "../src/libdecor.c"
#undef dlopen
#undef libdecor_frame_set_minimized
#undef libdecor_new
extern bool fl_libdecor_using_weston(void);
extern const struct libdecor_plugin_description *fl_libdecor_plugin_description;
//#include <stdio.h>
// we have a built-in plugin so don't need a fallback one
struct libdecor_plugin *libdecor_fallback_plugin_new(struct libdecor *context) {
return NULL;
}
// see get_libdecor_plugin_description() explaining why this is useful
static void *dlopen_corrected(const char *filename, int flags) {
static int best_priority = -1;
void *retval = dlopen(filename, flags);
if (retval) {
const struct libdecor_plugin_description *description =
(const struct libdecor_plugin_description*)dlsym(retval, "libdecor_plugin_description");
if (description && description->priorities->priority > best_priority) {
fl_libdecor_plugin_description = description;
best_priority = description->priorities->priority;
}
}
return retval;
}
LIBDECOR_EXPORT void libdecor_frame_set_minimized(struct libdecor_frame *frame)
{
static bool done = false;
static bool using_weston = false;
if (!done) {
typedef bool (*ext_f)(void);
volatile ext_f ext = fl_libdecor_using_weston;
done = true;
if (ext) using_weston = fl_libdecor_using_weston();
//fprintf(stderr, "fl_libdecor_using_weston=%p using_weston=%d\n", fl_libdecor_using_weston, using_weston);
if (using_weston) { // determine the version of the running Weston compositor
FILE *pipe = popen("weston --version", "r");
if (pipe) {
char line[50], *p;
int version = 0;
p = fgets(line, sizeof(line), pipe);
pclose(pipe);
if (p) p = strchr(line, ' ');
if (p) {
sscanf(p, "%d", &version);
// Weston version 10 has fixed the bug handled here
if (version >= 10) using_weston = false;
}
}
}
}
if (using_weston) libdecor_frame_set_visibility(frame, false);
libdecor_frame_set_minimized_orig(frame);
}
/*
By default, FLTK modifies libdecor's libdecor_new() function to determine the plugin as follows :
1) the directory pointed by environment variable LIBDECOR_PLUGIN_DIR or, in absence of this variable,
by -DLIBDECOR_PLUGIN_DIR=xxx at build time is searched for a libdecor plugin;
2) if this directory does not exist or contains no plugin, the built-in plugin is used.
* if FLTK was built with package libgtk-3-dev, the GTK plugin is used
* if FLTK was built without package libgtk-3-dev, the Cairo plugin is used
If FLTK was built with OPTION_USE_SYSTEM_LIBDECOR turned ON, the present modification
isn't compiled, so the plugin-searching algorithm of libdecor_new() in libdecor-0.so is used.
This corresponds to step 1) above and to use no titlebar is no plugin is found.
N.B.: only the system package is built with a meaningful value of -DLIBDECOR_PLUGIN_DIR=
so a plugin may be loaded that way only if FLTK was built with OPTION_USE_SYSTEM_LIBDECOR turned ON.
*/
LIBDECOR_EXPORT struct libdecor *libdecor_new(struct wl_display *wl_display, struct libdecor_interface *iface)
{
struct libdecor *context;
context = zalloc(sizeof *context);
context->ref_count = 1;
context->iface = iface;
context->wl_display = wl_display;
context->wl_registry = wl_display_get_registry(wl_display);
wl_registry_add_listener(context->wl_registry, ®istry_listener, context);
context->init_callback = wl_display_sync(context->wl_display);
wl_callback_add_listener(context->init_callback, &init_wl_display_callback_listener, context);
wl_list_init(&context->frames);
// attempt to dynamically load a libdecor plugin with dlopen()
if (init_plugins(context) != 0) { // attempt to load plugin by dlopen()
// no plug-in was found by dlopen(), use built-in plugin instead
// defined in the source code of the built-in plugin: libdecor-cairo.c or libdecor-gtk.c
extern const struct libdecor_plugin_description libdecor_plugin_description;
context->plugin = libdecor_plugin_description.constructor(context);
}
wl_display_flush(wl_display);
return context;
}
|