AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Protocol facts and explicit setters. Presentation choices stay in Sigil. */3
struct decoration {4
struct wl_list link;5
struct server *server;6
struct wlr_xdg_toplevel_decoration_v1 *native;7
struct wl_listener request,commit,destroy;8
uint64_t window,id;9
int mode;10
};11
static void decoration_request(struct wl_listener *listener,void *data) {12
(void)data;13
struct decoration *d=wl_container_of(listener,d,request);14
EVENT(75,d->window,d->native->requested_mode);15
}16
static void decoration_commit(struct wl_listener *listener,void *data) {17
(void)data;18
struct decoration *d=wl_container_of(listener,d,commit);19
if(d->mode && d->native->toplevel->base->initial_commit)20
wlr_xdg_toplevel_decoration_v1_set_mode(d->native,d->mode);21
}22
static void decoration_destroy(struct wl_listener *listener,void *data) {23
(void)data;24
struct decoration *d=wl_container_of(listener,d,destroy);25
EVENT(117,d->id);26
d->server->decoration_count--;27
atomic_fetch_sub(&bridge.objects,1);28
wl_list_remove(&d->request.link); wl_list_remove(&d->commit.link);29
wl_list_remove(&d->destroy.link); wl_list_remove(&d->link); free(d);30
}31
static void new_decoration(struct wl_listener *listener,void *data) {32
struct server *s=wl_container_of(listener,s,new_decoration);33
struct wlr_xdg_toplevel_decoration_v1 *native=data;34
struct view *v;35
uint64_t id=0;36
wl_list_for_each(v,&s->views,link) if(v->native==native->toplevel) { id=v->id; break; }37
if(!id) return;38
if(s->decoration_count>=256) { wl_resource_destroy(native->resource); return; }39
struct decoration *d=calloc(1,sizeof(*d));40
if(!d) return;41
d->server=s; d->native=native; d->window=id; d->id=++s->next_id;42
s->decoration_count++; atomic_fetch_add(&bridge.objects,1);43
wl_list_insert(&s->decorations,&d->link);44
listen(&native->events.request_mode,&d->request,decoration_request);45
listen(&native->toplevel->base->surface->events.commit,&d->commit,decoration_commit);46
listen(&native->events.destroy,&d->destroy,decoration_destroy);47
EVENT(116,d->id,id,0,0);48
EVENT(75,id,native->requested_mode);49
}50
static bool set_decoration_mode(struct server *s,uint64_t window,int mode) {51
if(mode<1 || mode>2) return false;52
struct decoration *d;53
wl_list_for_each(d,&s->decorations,link) {54
if(d->window!=window) continue;55
bool changed=d->mode!=mode;56
d->mode=mode;57
if(changed) EVENT(116,d->id,window,mode,0);58
if(d->native->toplevel->base->initialized)59
wlr_xdg_toplevel_decoration_v1_set_mode(d->native,mode);60
return true;61
}62
return false;63
}64
struct inhibitor {65
struct wl_list link;66
struct server *server;67
struct wlr_idle_inhibitor_v1 *native;68
uint64_t id,window;69
struct wl_listener destroy;70
};71
static void inhibitor_destroy(struct wl_listener *listener,void *data) {72
(void)data;73
struct inhibitor *i=wl_container_of(listener,i,destroy);74
EVENT(77,i->id);75
wl_list_remove(&i->destroy.link); wl_list_remove(&i->link);76
atomic_fetch_sub(&bridge.objects,1);77
free(i);78
}79
static void refresh_inhibitors(struct server *s) {80
struct inhibitor *inhibitor;81
wl_list_for_each(inhibitor,&s->inhibitors,link) {82
uint64_t window=window_for_surface(s,inhibitor->native->surface);83
if(window!=inhibitor->window) {84
inhibitor->window=window;85
EVENT(76,inhibitor->id,window);86
}87
}88
}89
static void new_inhibitor(struct wl_listener *listener,void *data) {90
struct server *s=wl_container_of(listener,s,new_inhibitor);91
struct wlr_idle_inhibitor_v1 *native=data;92
struct inhibitor *inhibitor=calloc(1,sizeof(*inhibitor));93
if(!inhibitor) return;94
inhibitor->server=s; inhibitor->id=++s->next_id; inhibitor->native=native;95
inhibitor->window=window_for_surface(s,native->surface);96
wl_list_insert(&s->inhibitors,&inhibitor->link);97
listen(&native->events.destroy,&inhibitor->destroy,inhibitor_destroy);98
atomic_fetch_add(&bridge.objects,1);99
EVENT(76,inhibitor->id,inhibitor->window);100
}101
static bool configure_cursor(struct server *s,const int64_t *w,size_t count) {102
if(count<3 || w[0]<1 || w[0]>512 || w[1]<0 || w[1]>128 || w[2]<0 || w[2]>128 ||103
count!=3+(size_t)w[1]+(size_t)w[2]) return false;104
char name[129]={0},theme[129]={0};105
for(int i=0;i<w[1]+w[2];i++) {106
if(w[3+i]<32 || w[3+i]>126) return false;107
if(i<w[1]) name[i]=w[3+i]; else theme[i-w[1]]=w[3+i];108
}109
if(!w[1]) { wlr_cursor_unset_image(s->cursor); return true; }110
struct wlr_xcursor_manager *manager=wlr_xcursor_manager_create(w[2] ? theme : NULL,w[0]);111
if(!manager) return false;112
wlr_cursor_set_xcursor(s->cursor,manager,name);113
if(s->cursor_manager) wlr_xcursor_manager_destroy(s->cursor_manager);114
s->cursor_manager=manager;115
return true;116
}