[digesting_libdecor] split state field out of hdr element, delete dead code, eliminate reducible functions
parent
6e0c97bfcd
commit
bea30ea7de
|
|
@ -160,18 +160,18 @@ pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time,
|
||||||
wl_pointer_set_cursor(seat->wl_pointer, seat->serial, seat->cursor_surface, image->hotspot_x, image->hotspot_y);
|
wl_pointer_set_cursor(seat->wl_pointer, seat->serial, seat->cursor_surface, image->hotspot_x, image->hotspot_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* avoid warnings after decoration has been turned off */
|
|
||||||
if (!GTK_IS_WIDGET(ctx.header) || ctx.active != COMPONENT_SLOT_HEADER){
|
if (!GTK_IS_WIDGET(ctx.header) || ctx.active != COMPONENT_SLOT_HEADER){
|
||||||
ctx.hdr_focus.type = HEADER_NONE;
|
ctx.hdr_focus.type = HEADER_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), seat->pointer_x, seat->pointer_y);
|
new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), seat->pointer_x, seat->pointer_y);
|
||||||
|
|
||||||
/* only update if widget change so that we keep the state */
|
/* only update if widget change so that we keep the state */
|
||||||
if (ctx.hdr_focus.widget != new_focus.widget){
|
if (ctx.hdr_focus.widget != new_focus.widget){
|
||||||
ctx.hdr_focus = new_focus;
|
ctx.hdr_focus = new_focus;
|
||||||
|
ctx.hdr_state = 0;
|
||||||
}
|
}
|
||||||
ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT;
|
ctx.hdr_state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
|
|
||||||
/* redraw with updated button visuals */
|
/* redraw with updated button visuals */
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
|
|
@ -236,7 +236,7 @@ pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
case HEADER_MIN:
|
case HEADER_MIN:
|
||||||
case HEADER_MAX:
|
case HEADER_MAX:
|
||||||
case HEADER_CLOSE: {
|
case HEADER_CLOSE: {
|
||||||
ctx.hdr_focus.state |= GTK_STATE_FLAG_ACTIVE;
|
ctx.hdr_state |= GTK_STATE_FLAG_ACTIVE;
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
}break;
|
}break;
|
||||||
|
|
@ -281,7 +281,7 @@ pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE;
|
ctx.hdr_state &= ~GTK_STATE_FLAG_ACTIVE;
|
||||||
if (GTK_IS_WIDGET(ctx.header)){
|
if (GTK_IS_WIDGET(ctx.header)){
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
|
|
@ -289,7 +289,7 @@ pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
ctx.hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE;
|
ctx.hdr_state &= ~GTK_STATE_FLAG_ACTIVE;
|
||||||
if (GTK_IS_WIDGET(ctx.header)) {
|
if (GTK_IS_WIDGET(ctx.header)) {
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
|
|
@ -364,7 +364,7 @@ touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial,
|
||||||
case HEADER_MIN:
|
case HEADER_MIN:
|
||||||
case HEADER_MAX:
|
case HEADER_MAX:
|
||||||
case HEADER_CLOSE: {
|
case HEADER_CLOSE: {
|
||||||
ctx.hdr_focus.state |= GTK_STATE_FLAG_ACTIVE;
|
ctx.hdr_state |= GTK_STATE_FLAG_ACTIVE;
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
}break;
|
}break;
|
||||||
|
|
@ -398,7 +398,7 @@ touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time,
|
||||||
if (seat->touch_focus && own_proxy(seat->touch_focus)){
|
if (seat->touch_focus && own_proxy(seat->touch_focus)){
|
||||||
if (ctx.touch_active != 0){
|
if (ctx.touch_active != 0){
|
||||||
if (ctx.touch_active == COMPONENT_SLOT_HEADER){
|
if (ctx.touch_active == COMPONENT_SLOT_HEADER){
|
||||||
switch (ctx.hdr_focus.type) {
|
switch (ctx.hdr_focus.type){
|
||||||
case HEADER_MIN: {
|
case HEADER_MIN: {
|
||||||
if (ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE){
|
if (ctx.frame_capabilities & LIBDECOR_ACTION_MINIMIZE){
|
||||||
xdg_toplevel_set_minimized(ctx.xdg_toplevel);
|
xdg_toplevel_set_minimized(ctx.xdg_toplevel);
|
||||||
|
|
@ -422,19 +422,20 @@ touch_up(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unset active/clicked state once released */
|
/* unset active/clicked state once released */
|
||||||
ctx.hdr_focus.state &= ~GTK_STATE_FLAG_ACTIVE;
|
ctx.hdr_state &= ~GTK_STATE_FLAG_ACTIVE;
|
||||||
if (GTK_IS_WIDGET(ctx.header)) {
|
if (GTK_IS_WIDGET(ctx.header)) {
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
seat->touch_focus = 0;
|
seat->touch_focus = 0;
|
||||||
ctx.touch_active = 0;
|
ctx.touch_active = 0;
|
||||||
ctx.hdr_focus.widget = 0;
|
ctx.hdr_focus.widget = 0;
|
||||||
ctx.hdr_focus.type = HEADER_NONE;
|
ctx.hdr_focus.type = HEADER_NONE;
|
||||||
draw_decoration();
|
draw_decoration();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -716,7 +717,8 @@ const struct xdg_toplevel_listener xdg_toplevel_listener = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_toplevel_decoration_configure(void *data, struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode){
|
xdg_toplevel_decoration_configure(void *data, struct zxdg_toplevel_decoration_v1 *toplevel,
|
||||||
|
uint32_t mode){
|
||||||
if (!ctx.has_decoration_mode){
|
if (!ctx.has_decoration_mode){
|
||||||
ctx.has_decoration_mode = true;
|
ctx.has_decoration_mode = true;
|
||||||
ctx.decoration_mode = mode;
|
ctx.decoration_mode = mode;
|
||||||
|
|
@ -954,7 +956,6 @@ int main(){
|
||||||
xdg_toplevel_set_title(ctx.xdg_toplevel, "Example Window");
|
xdg_toplevel_set_title(ctx.xdg_toplevel, "Example Window");
|
||||||
ctx.title = strdup("Example Window");
|
ctx.title = strdup("Example Window");
|
||||||
|
|
||||||
draw_decoration();
|
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
|
|
||||||
/* (nodocs-wl_egl) */
|
/* (nodocs-wl_egl) */
|
||||||
|
|
@ -1011,16 +1012,11 @@ int main(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (egl) eglMakeCurrent */
|
|
||||||
EGLBoolean make_current_success2 = 0;
|
EGLBoolean make_current_success2 = 0;
|
||||||
if (ctx.egl_surface != EGL_NO_SURFACE){
|
if (ctx.egl_surface != EGL_NO_SURFACE){
|
||||||
make_current_success2 = eglMakeCurrent(ctx.egl_display, ctx.egl_surface, ctx.egl_surface, ctx.egl_context);
|
make_current_success2 = eglMakeCurrent(ctx.egl_display, ctx.egl_surface, ctx.egl_surface, ctx.egl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (egl) eglSwapInterval
|
|
||||||
** " specifies the minimum number of video frame periods per buffer swap
|
|
||||||
** for the window associated with the current context "
|
|
||||||
*/
|
|
||||||
EGLBoolean swap_interval_success = 0;
|
EGLBoolean swap_interval_success = 0;
|
||||||
if (make_current_success2){
|
if (make_current_success2){
|
||||||
swap_interval_success = eglSwapInterval(ctx.egl_display, 1);
|
swap_interval_success = eglSwapInterval(ctx.egl_display, 1);
|
||||||
|
|
@ -1073,10 +1069,7 @@ int main(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.close_signal){
|
/* apply new surface config */
|
||||||
exit_loop = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx.has_cached_config){
|
if (ctx.has_cached_config){
|
||||||
ctx.has_cached_config = 0;
|
ctx.has_cached_config = 0;
|
||||||
if (ctx.cached_config.initialized){
|
if (ctx.cached_config.initialized){
|
||||||
|
|
@ -1099,6 +1092,10 @@ int main(){
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx.close_signal){
|
||||||
|
exit_loop = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* (egl) eglSwapBuffers
|
/* (egl) eglSwapBuffers
|
||||||
** " back-buffered window surface, then the color buffer is copied
|
** " back-buffered window surface, then the color buffer is copied
|
||||||
** (posted) to the native window associated with that surface "
|
** (posted) to the native window associated with that surface "
|
||||||
|
|
@ -1169,28 +1166,6 @@ decoration_type_from_window_state(enum libdecor_window_state window_state){
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
free_border_component(struct border_component *border_component){
|
|
||||||
if (border_component->wl_surface) {
|
|
||||||
wl_subsurface_destroy(border_component->wl_subsurface);
|
|
||||||
border_component->wl_subsurface = NULL;
|
|
||||||
wl_surface_destroy(border_component->wl_surface);
|
|
||||||
border_component->wl_surface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (border_component->wl_buffer != 0){
|
|
||||||
wl_buffer_destroy(border_component->wl_buffer);
|
|
||||||
}
|
|
||||||
if (border_component->data != 0){
|
|
||||||
munmap(border_component->data, border_component->data_size);
|
|
||||||
}
|
|
||||||
border_component->wl_buffer = 0;
|
|
||||||
border_component->data = 0;
|
|
||||||
border_component->data_size = 0;
|
|
||||||
border_component->width = 0;
|
|
||||||
border_component->height = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum xdg_toplevel_resize_edge
|
static enum xdg_toplevel_resize_edge
|
||||||
xdg_edge_from_edge(enum libdecor_resize_edge edge){
|
xdg_edge_from_edge(enum libdecor_resize_edge edge){
|
||||||
enum xdg_toplevel_resize_edge result = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
enum xdg_toplevel_resize_edge result = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||||
|
|
@ -1208,26 +1183,19 @@ xdg_edge_from_edge(enum libdecor_resize_edge edge){
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
libdecor_frame_set_fullscreen(struct wl_output *output){
|
|
||||||
xdg_toplevel_set_fullscreen(ctx.xdg_toplevel, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
libdecor_frame_unset_fullscreen(void){
|
|
||||||
xdg_toplevel_unset_fullscreen(ctx.xdg_toplevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
libdecor_frame_commit(void){
|
libdecor_frame_commit(void){
|
||||||
Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
|
|
||||||
|
|
||||||
bool csd = false;
|
bool csd = false;
|
||||||
if (ctx.visible &&
|
if (ctx.visible &&
|
||||||
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
|
||||||
csd = true;
|
csd = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sides2D border_size = {0};
|
||||||
|
if (csd){
|
||||||
|
border_size = border_size_from_window_state(ctx.frame_window_state);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
if (!(ctx.frame_capabilities & LIBDECOR_ACTION_RESIZE)){
|
||||||
int mw = ctx.frame_content_width;
|
int mw = ctx.frame_content_width;
|
||||||
int mh = ctx.frame_content_height;
|
int mh = ctx.frame_content_height;
|
||||||
|
|
@ -1270,8 +1238,28 @@ libdecor_frame_commit(void){
|
||||||
g_clear_pointer(&ctx.header, gtk_widget_destroy);
|
g_clear_pointer(&ctx.header, gtk_widget_destroy);
|
||||||
g_clear_pointer(&ctx.window, gtk_widget_destroy);
|
g_clear_pointer(&ctx.window, gtk_widget_destroy);
|
||||||
|
|
||||||
free_border_component(&ctx.component_slot[COMPONENT_SLOT_HEADER]);
|
for (int i = 1; i < COMPONENT_SLOT_COUNT; i += 1){
|
||||||
free_border_component(&ctx.component_slot[COMPONENT_SLOT_SHADOW]);
|
struct border_component * border_component = &ctx.component_slot[i];
|
||||||
|
if (border_component->wl_subsurface != 0){
|
||||||
|
wl_subsurface_destroy(border_component->wl_subsurface);
|
||||||
|
border_component->wl_subsurface = 0;
|
||||||
|
}
|
||||||
|
if (border_component->wl_surface != 0){
|
||||||
|
wl_surface_destroy(border_component->wl_surface);
|
||||||
|
border_component->wl_surface = 0;
|
||||||
|
}
|
||||||
|
if (border_component->wl_buffer != 0){
|
||||||
|
wl_buffer_destroy(border_component->wl_buffer);
|
||||||
|
border_component->wl_buffer = 0;
|
||||||
|
}
|
||||||
|
if (border_component->data != 0){
|
||||||
|
munmap(border_component->data, border_component->data_size);
|
||||||
|
border_component->data = 0;
|
||||||
|
}
|
||||||
|
border_component->data_size = 0;
|
||||||
|
border_component->width = 0;
|
||||||
|
border_component->height = 0;
|
||||||
|
}
|
||||||
ctx.shadow_showing = false;
|
ctx.shadow_showing = false;
|
||||||
|
|
||||||
g_clear_pointer(&ctx.title, free);
|
g_clear_pointer(&ctx.title, free);
|
||||||
|
|
@ -1283,7 +1271,6 @@ libdecor_frame_commit(void){
|
||||||
Extent2D extent = {0};
|
Extent2D extent = {0};
|
||||||
extent.w = ctx.frame_content_width;
|
extent.w = ctx.frame_content_width;
|
||||||
extent.h = ctx.frame_content_height;
|
extent.h = ctx.frame_content_height;
|
||||||
|
|
||||||
if (csd){
|
if (csd){
|
||||||
extent.x = -border_size.x[0];
|
extent.x = -border_size.x[0];
|
||||||
extent.y = -border_size.y[0];
|
extent.y = -border_size.y[0];
|
||||||
|
|
@ -1546,200 +1533,161 @@ render_shadow(cairo_t *cr, cairo_surface_t *surface,
|
||||||
//#include "os-compatibility.c"
|
//#include "os-compatibility.c"
|
||||||
#ifndef HAVE_MKOSTEMP
|
#ifndef HAVE_MKOSTEMP
|
||||||
static int
|
static int
|
||||||
set_cloexec_or_close(int fd)
|
set_cloexec_or_close(int fd){
|
||||||
{
|
bool error = 0;
|
||||||
long flags;
|
long flags;
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd >= 0){
|
||||||
return -1;
|
if (fcntl(fd, F_GETFD) == -1){
|
||||||
|
error = 1;
|
||||||
flags = fcntl(fd, F_GETFD);
|
}
|
||||||
if (flags == -1)
|
else if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1){
|
||||||
goto err;
|
error = 1;
|
||||||
|
}
|
||||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
|
||||||
goto err;
|
if (error){
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
err:
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
create_tmpfile_cloexec(char *tmpname)
|
create_tmpfile_cloexec(char *tmpname){
|
||||||
{
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
#ifdef HAVE_MKOSTEMP
|
#ifdef HAVE_MKOSTEMP
|
||||||
fd = mkostemp(tmpname, O_CLOEXEC);
|
fd = mkostemp(tmpname, O_CLOEXEC);
|
||||||
if (fd >= 0)
|
if (fd >= 0){
|
||||||
unlink(tmpname);
|
unlink(tmpname);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
fd = mkstemp(tmpname);
|
fd = mkstemp(tmpname);
|
||||||
|
fd = set_cloexec_or_close(fd);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
fd = set_cloexec_or_close(fd);
|
|
||||||
unlink(tmpname);
|
unlink(tmpname);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return fd;
|
return(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
os_resize_anonymous_file(int fd, off_t size)
|
os_resize_anonymous_file(int fd, off_t size){
|
||||||
{
|
|
||||||
#ifdef HAVE_POSIX_FALLOCATE
|
#ifdef HAVE_POSIX_FALLOCATE
|
||||||
|
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
sigset_t old_mask;
|
sigset_t old_mask;
|
||||||
|
|
||||||
/* posix_fallocate() might be interrupted, so we need to check
|
|
||||||
* for EINTR and retry in that case.
|
|
||||||
* However, in the presence of an alarm, the interrupt may trigger
|
|
||||||
* repeatedly and prevent a large posix_fallocate() to ever complete
|
|
||||||
* successfully, so we need to first block SIGALRM to prevent
|
|
||||||
* this.
|
|
||||||
*/
|
|
||||||
sigemptyset(&mask);
|
sigemptyset(&mask);
|
||||||
sigaddset(&mask, SIGALRM);
|
sigaddset(&mask, SIGALRM);
|
||||||
sigprocmask(SIG_BLOCK, &mask, &old_mask);
|
sigprocmask(SIG_BLOCK, &mask, &old_mask);
|
||||||
/*
|
|
||||||
* Filesystems that do not support fallocate will return EINVAL or
|
|
||||||
* EOPNOTSUPP. In this case we need to fall back to ftruncate
|
|
||||||
*/
|
|
||||||
do {
|
do {
|
||||||
errno = posix_fallocate(fd, 0, size);
|
errno = posix_fallocate(fd, 0, size);
|
||||||
} while (errno == EINTR);
|
} while (errno == EINTR);
|
||||||
sigprocmask(SIG_SETMASK, &old_mask, NULL);
|
sigprocmask(SIG_SETMASK, &old_mask, NULL);
|
||||||
if (errno == 0)
|
|
||||||
return 0;
|
|
||||||
else if (errno != EINVAL && errno != EOPNOTSUPP)
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
if (ftruncate(fd, size) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
int result = 0;
|
||||||
|
if (errno != 0){
|
||||||
|
result = -1;
|
||||||
|
if (errno == EINVAL || errno == EOPNOTSUPP){
|
||||||
|
if (ftruncate(fd, size) >= 0){
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int result = -1;
|
||||||
|
if (ftruncate(fd, size) >= 0){
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new, unique, anonymous file of the given size, and
|
|
||||||
* return the file descriptor for it. The file descriptor is set
|
|
||||||
* CLOEXEC. The file is immediately suitable for mmap()'ing
|
|
||||||
* the given size at offset zero.
|
|
||||||
*
|
|
||||||
* The file should not have a permanent backing store like a disk,
|
|
||||||
* but may have if XDG_RUNTIME_DIR is not properly implemented in OS.
|
|
||||||
*
|
|
||||||
* The file name is deleted from the file system.
|
|
||||||
*
|
|
||||||
* The file is suitable for buffer sharing between processes by
|
|
||||||
* transmitting the file descriptor over Unix sockets using the
|
|
||||||
* SCM_RIGHTS methods.
|
|
||||||
*
|
|
||||||
* If the C library implements posix_fallocate(), it is used to
|
|
||||||
* guarantee that disk space is available for the file at the
|
|
||||||
* given size. If disk space is insufficient, errno is set to ENOSPC.
|
|
||||||
* If posix_fallocate() is not supported, program may receive
|
|
||||||
* SIGBUS on accessing mmap()'ed file contents instead.
|
|
||||||
*
|
|
||||||
* If the C library implements memfd_create(), it is used to create the
|
|
||||||
* file purely in memory, without any backing file name on the file
|
|
||||||
* system, and then sealing off the possibility of shrinking it. This
|
|
||||||
* can then be checked before accessing mmap()'ed file contents, to
|
|
||||||
* make sure SIGBUS can't happen. It also avoids requiring
|
|
||||||
* XDG_RUNTIME_DIR.
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
libdecor_os_create_anonymous_file(off_t size){
|
libdecor_os_create_anonymous_file(off_t size){
|
||||||
static const char template[] = "/libdecor-shared-XXXXXX";
|
static const char key[] = "/libdecor-shared-XXXXXX";
|
||||||
const char *path;
|
int fd = -1;
|
||||||
char *name;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
#ifdef HAVE_MEMFD_CREATE
|
#ifdef HAVE_MEMFD_CREATE
|
||||||
fd = memfd_create("libdecor", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
fd = memfd_create("libdecor", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||||
if (fd >= 0) {
|
if (fd >= 0){
|
||||||
/* We can add this seal before calling posix_fallocate(), as
|
|
||||||
* the file is currently zero-sized anyway.
|
|
||||||
*
|
|
||||||
* There is also no need to check for the return value, we
|
|
||||||
* couldn't do anything with it anyway.
|
|
||||||
*/
|
|
||||||
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL);
|
||||||
} else
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
path = getenv("XDG_RUNTIME_DIR");
|
if (fd < 0){
|
||||||
if (!path) {
|
const char *path = getenv("XDG_RUNTIME_DIR");
|
||||||
|
if (path == 0){
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
name = malloc(strlen(path) + sizeof(template));
|
char *name = malloc(strlen(path) + sizeof(key));
|
||||||
if (!name)
|
if (name != 0){
|
||||||
return -1;
|
strcpy(name, path);
|
||||||
|
strcat(name, key);
|
||||||
strcpy(name, path);
|
fd = create_tmpfile_cloexec(name);
|
||||||
strcat(name, template);
|
free(name);
|
||||||
|
}
|
||||||
fd = create_tmpfile_cloexec(name);
|
}
|
||||||
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (os_resize_anonymous_file(fd, size) < 0) {
|
if (fd >= 0 && os_resize_anonymous_file(fd, size) < 0){
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#include "plugins/gtk/libdecor-gtk.c"
|
//#include "plugins/gtk/libdecor-gtk.c"
|
||||||
|
|
||||||
|
struct find_widget_variables{
|
||||||
|
char *name;
|
||||||
|
GtkWidget *widget;
|
||||||
|
} find_widget_variables;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_fill_widget_from_name(GtkWidget *widget, void *data){
|
fill_widget_from_name(GtkWidget *widget, void *data){
|
||||||
bool match = false;
|
struct find_widget_variables *vars = data;
|
||||||
if (GTK_IS_WIDGET(widget)){
|
if (vars->widget == 0){
|
||||||
struct header_element_data *elem = data;
|
bool match = false;
|
||||||
GtkStyleContext *style_context = gtk_widget_get_style_context(widget);
|
if (GTK_IS_WIDGET(widget)){
|
||||||
char *style_ctx = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
|
GtkStyleContext *style_context = gtk_widget_get_style_context(widget);
|
||||||
if (strstr(style_ctx, elem->name) != 0){
|
char *style_str = gtk_style_context_to_string(style_context, GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE);
|
||||||
elem->widget = widget;
|
if (strstr(style_str, vars->name) != 0){
|
||||||
match = true;
|
vars->widget = widget;
|
||||||
|
match = true;
|
||||||
|
}
|
||||||
|
free(style_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match && GTK_IS_CONTAINER(widget)){
|
||||||
|
gtk_container_forall(GTK_CONTAINER(widget), &fill_widget_from_name, data);
|
||||||
}
|
}
|
||||||
free(style_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* recursively traverse container */
|
|
||||||
if (!match && GTK_IS_CONTAINER(widget)){
|
|
||||||
gtk_container_forall(GTK_CONTAINER(widget), >k_fill_widget_from_name, data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct header_element_data
|
static GtkWidget*
|
||||||
find_widget_by_type(GtkWidget *widget, enum header_element type){
|
find_widget_by_type(GtkWidget *root, enum header_element type){
|
||||||
char* name = 0;
|
struct find_widget_variables vars = {0};
|
||||||
switch (type){
|
switch (type){
|
||||||
case HEADER_FULL: name = "headerbar.titlebar:"; break;
|
case HEADER_FULL: vars.name = "headerbar.titlebar:"; break;
|
||||||
case HEADER_TITLE: name = "label.title:"; break;
|
case HEADER_TITLE: vars.name = "label.title:"; break;
|
||||||
case HEADER_MIN: name = ".minimize"; break;
|
case HEADER_MIN: vars.name = ".minimize"; break;
|
||||||
case HEADER_MAX: name = ".maximize"; break;
|
case HEADER_MAX: vars.name = ".maximize"; break;
|
||||||
case HEADER_CLOSE: name = ".close"; break;
|
case HEADER_CLOSE: vars.name = ".close"; break;
|
||||||
default:break;
|
default:break;
|
||||||
}
|
}
|
||||||
|
fill_widget_from_name(root, &vars);
|
||||||
struct header_element_data data = {0};
|
return(vars.widget);
|
||||||
data.name = name;
|
|
||||||
data.type = type;
|
|
||||||
gtk_fill_widget_from_name(widget, &data);
|
|
||||||
return(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct header_element_data
|
static struct header_element_data
|
||||||
|
|
@ -1748,13 +1696,14 @@ get_header_focus(const GtkHeaderBar *header_bar, int x, int y){
|
||||||
struct header_element_data result = {0};
|
struct header_element_data result = {0};
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_LENGTH(elems); i += 1){
|
for (size_t i = 0; i < ARRAY_LENGTH(elems); i += 1){
|
||||||
struct header_element_data elem = find_widget_by_type(GTK_WIDGET(header_bar), elems[i]);
|
GtkWidget *widget = find_widget_by_type(GTK_WIDGET(header_bar), elems[i]);
|
||||||
if (elem.widget){
|
if (widget != 0){
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
gtk_widget_get_allocation(GTK_WIDGET(elem.widget), &allocation);
|
gtk_widget_get_allocation(GTK_WIDGET(widget), &allocation);
|
||||||
if (allocation.x <= x && x < allocation.x + allocation.width &&
|
if (allocation.x <= x && x < allocation.x + allocation.width &&
|
||||||
allocation.y <= y && y < allocation.y + allocation.height){
|
allocation.y <= y && y < allocation.y + allocation.height){
|
||||||
result = elem;
|
result.type = elems[i];
|
||||||
|
result.widget = widget;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1897,10 +1846,7 @@ array_append(enum header_element **array, size_t *n, enum header_element item){
|
||||||
static void
|
static void
|
||||||
draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
||||||
enum header_element button_type){
|
enum header_element button_type){
|
||||||
struct header_element_data elem;
|
|
||||||
GtkWidget *button;
|
GtkWidget *button;
|
||||||
GtkStyleContext* button_style;
|
|
||||||
GtkStateFlags style_state;
|
|
||||||
|
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
|
|
||||||
|
|
@ -1922,19 +1868,18 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
|
||||||
GtkBorder border;
|
GtkBorder border;
|
||||||
GtkBorder padding;
|
GtkBorder padding;
|
||||||
|
|
||||||
elem = find_widget_by_type(ctx.header, button_type);
|
button = find_widget_by_type(ctx.header, button_type);
|
||||||
button = elem.widget;
|
|
||||||
if (button){
|
if (button){
|
||||||
button_style = gtk_widget_get_style_context(button);
|
GtkStyleContext *button_style = gtk_widget_get_style_context(button);
|
||||||
style_state = elem.state;
|
GtkStateFlags style_state = 0;
|
||||||
|
|
||||||
/* change style based on window state and focus */
|
/* change style based on window state and focus */
|
||||||
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_ACTIVE)) {
|
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
||||||
style_state |= GTK_STATE_FLAG_BACKDROP;
|
style_state |= GTK_STATE_FLAG_BACKDROP;
|
||||||
}
|
}
|
||||||
if (ctx.hdr_focus.widget == button) {
|
if (ctx.hdr_focus.widget == button){
|
||||||
style_state |= GTK_STATE_FLAG_PRELIGHT;
|
style_state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
if (ctx.hdr_focus.state & GTK_STATE_FLAG_ACTIVE) {
|
if (ctx.hdr_state & GTK_STATE_FLAG_ACTIVE){
|
||||||
style_state |= GTK_STATE_FLAG_ACTIVE;
|
style_state |= GTK_STATE_FLAG_ACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2037,7 +1982,7 @@ static void
|
||||||
draw_border_component(enum component_slot slot){
|
draw_border_component(enum component_slot slot){
|
||||||
if (slot < COMPONENT_SLOT_COUNT &&
|
if (slot < COMPONENT_SLOT_COUNT &&
|
||||||
ctx.component_slot[slot].wl_surface != 0){
|
ctx.component_slot[slot].wl_surface != 0){
|
||||||
Extent2D extent = extent2d_from_component_slot(slot);
|
struct border_component *component = &ctx.component_slot[slot];
|
||||||
|
|
||||||
if (slot == COMPONENT_SLOT_SHADOW && ctx.shadow_showing){
|
if (slot == COMPONENT_SLOT_SHADOW && ctx.shadow_showing){
|
||||||
struct wl_region *input_region;
|
struct wl_region *input_region;
|
||||||
|
|
@ -2045,26 +1990,25 @@ draw_border_component(enum component_slot slot){
|
||||||
input_region = wl_compositor_create_region(ctx.wl_compositor);
|
input_region = wl_compositor_create_region(ctx.wl_compositor);
|
||||||
wl_region_add(input_region, 0, 0, extent.w, extent.h);
|
wl_region_add(input_region, 0, 0, extent.w, extent.h);
|
||||||
wl_region_subtract(input_region, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height);
|
wl_region_subtract(input_region, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height);
|
||||||
wl_surface_set_input_region(ctx.component_slot[slot].wl_surface, input_region);
|
wl_surface_set_input_region(component->wl_surface, input_region);
|
||||||
wl_region_destroy(input_region);
|
wl_region_destroy(input_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct border_component *component = &ctx.component_slot[slot];
|
|
||||||
|
|
||||||
{
|
{
|
||||||
if (component->wl_buffer != 0){
|
if (component->wl_buffer != 0){
|
||||||
wl_buffer_destroy(component->wl_buffer);
|
wl_buffer_destroy(component->wl_buffer);
|
||||||
|
component->wl_buffer = 0;
|
||||||
}
|
}
|
||||||
if (component->data != 0){
|
if (component->data != 0){
|
||||||
munmap(component->data, component->data_size);
|
munmap(component->data, component->data_size);
|
||||||
|
component->data = 0;
|
||||||
}
|
}
|
||||||
component->wl_buffer = 0;
|
|
||||||
component->data = 0;
|
|
||||||
component->data_size = 0;
|
component->data_size = 0;
|
||||||
component->width = 0;
|
component->width = 0;
|
||||||
component->height = 0;
|
component->height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Extent2D extent = extent2d_from_component_slot(slot);
|
||||||
{
|
{
|
||||||
int width = extent.w;
|
int width = extent.w;
|
||||||
int height = extent.h;
|
int height = extent.h;
|
||||||
|
|
@ -2125,7 +2069,7 @@ draw_border_component(enum component_slot slot){
|
||||||
|
|
||||||
/* title */
|
/* title */
|
||||||
{
|
{
|
||||||
GtkWidget *label = find_widget_by_type(ctx.header, HEADER_TITLE).widget;
|
GtkWidget *label = find_widget_by_type(ctx.header, HEADER_TITLE);
|
||||||
|
|
||||||
GtkAllocation allocation;
|
GtkAllocation allocation;
|
||||||
gtk_widget_get_allocation(label, &allocation);
|
gtk_widget_get_allocation(label, &allocation);
|
||||||
|
|
@ -2182,11 +2126,7 @@ draw_border_component(enum component_slot slot){
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_title_bar(void){
|
draw_title_bar(void){
|
||||||
enum libdecor_window_state state;
|
enum libdecor_window_state state = ctx.frame_window_state;
|
||||||
GtkStyleContext *style;
|
|
||||||
|
|
||||||
state = ctx.frame_window_state;
|
|
||||||
style = gtk_widget_get_style_context(ctx.window);
|
|
||||||
|
|
||||||
if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
if (!(state & LIBDECOR_WINDOW_STATE_ACTIVE)){
|
||||||
gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true);
|
gtk_widget_set_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP, true);
|
||||||
|
|
@ -2194,14 +2134,13 @@ draw_title_bar(void){
|
||||||
else{
|
else{
|
||||||
gtk_widget_unset_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP);
|
gtk_widget_unset_state_flags(ctx.window, GTK_STATE_FLAG_BACKDROP);
|
||||||
}
|
}
|
||||||
|
GtkStyleContext *style = gtk_widget_get_style_context(ctx.window);
|
||||||
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_NON_FLOATING)){
|
if (!(ctx.frame_window_state & LIBDECOR_WINDOW_STATE_NON_FLOATING)){
|
||||||
gtk_style_context_remove_class(style, "maximized");
|
gtk_style_context_remove_class(style, "maximized");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
gtk_style_context_add_class(style, "maximized");
|
gtk_style_context_add_class(style, "maximized");
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_show_all(ctx.window);
|
gtk_widget_show_all(ctx.window);
|
||||||
|
|
||||||
int pref_width;
|
int pref_width;
|
||||||
|
|
@ -2327,8 +2266,9 @@ update_touch_focus(struct seat *seat, wl_fixed_t x, wl_fixed_t y){
|
||||||
struct header_element_data new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), wl_fixed_to_int(x), wl_fixed_to_int(y));
|
struct header_element_data new_focus = get_header_focus(GTK_HEADER_BAR(ctx.header), wl_fixed_to_int(x), wl_fixed_to_int(y));
|
||||||
if (ctx.hdr_focus.widget != new_focus.widget){
|
if (ctx.hdr_focus.widget != new_focus.widget){
|
||||||
ctx.hdr_focus = new_focus;
|
ctx.hdr_focus = new_focus;
|
||||||
|
ctx.hdr_state = 0;
|
||||||
}
|
}
|
||||||
ctx.hdr_focus.state |= GTK_STATE_FLAG_PRELIGHT;
|
ctx.hdr_state |= GTK_STATE_FLAG_PRELIGHT;
|
||||||
draw_title_bar();
|
draw_title_bar();
|
||||||
wl_surface_commit(ctx.wl_surface);
|
wl_surface_commit(ctx.wl_surface);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,11 +146,9 @@ enum titlebar_gesture_state {
|
||||||
TITLEBAR_GESTURE_STATE_DISCARDED,
|
TITLEBAR_GESTURE_STATE_DISCARDED,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct header_element_data {
|
struct header_element_data{
|
||||||
const char *name;
|
|
||||||
enum header_element type;
|
enum header_element type;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
GtkStateFlags state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum decoration_type {
|
enum decoration_type {
|
||||||
|
|
@ -253,8 +251,6 @@ enum titlebar_gesture {
|
||||||
void libdecor_frame_show_window_menu(struct wl_seat *wl_seat, uint32_t serial, int x, int y);
|
void libdecor_frame_show_window_menu(struct wl_seat *wl_seat, uint32_t serial, int x, int y);
|
||||||
|
|
||||||
void libdecor_frame_commit(void);
|
void libdecor_frame_commit(void);
|
||||||
void libdecor_frame_set_fullscreen(struct wl_output *output);
|
|
||||||
void libdecor_frame_unset_fullscreen(void);
|
|
||||||
|
|
||||||
// #include "libdecor-cairo-blur.h"
|
// #include "libdecor-cairo-blur.h"
|
||||||
|
|
||||||
|
|
@ -281,8 +277,6 @@ static void do_map(void);
|
||||||
|
|
||||||
static const char *libdecor_gtk_proxy_tag = "libdecor-gtk";
|
static const char *libdecor_gtk_proxy_tag = "libdecor-gtk";
|
||||||
|
|
||||||
static void libdecor_plugin_gtk_frame_free(void);
|
|
||||||
static void libdecor_plugin_gtk_frame_commit(void);
|
|
||||||
static Sides2D border_size_from_window_state(enum libdecor_window_state window_state);
|
static Sides2D border_size_from_window_state(enum libdecor_window_state window_state);
|
||||||
|
|
||||||
static struct wl_cursor* wl_cursor_from_pos(int x, int y);
|
static struct wl_cursor* wl_cursor_from_pos(int x, int y);
|
||||||
|
|
@ -386,6 +380,7 @@ typedef struct Ctx{
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *header;
|
GtkWidget *header;
|
||||||
struct header_element_data hdr_focus;
|
struct header_element_data hdr_focus;
|
||||||
|
GtkStateFlags hdr_state;
|
||||||
|
|
||||||
cairo_surface_t *shadow_blur;
|
cairo_surface_t *shadow_blur;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue