AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Protocol handles and request transport. Window policy stays in Sigil. */3
static const char *foreign_title(struct view *v) {4
const char *title=v->x11 ? v->x11->title : v->native->title;5
return title ? title : "";6
}7
static const char *foreign_app_id(struct view *v) {8
const char *app_id=v->x11 ? v->x11->class : v->native->app_id;9
return app_id ? app_id : "";10
}11
static void foreign_metadata(struct view *v) {12
if(v->foreign_list) {13
struct wlr_ext_foreign_toplevel_handle_v1_state state={14
.title=foreign_title(v),.app_id=foreign_app_id(v)};15
wlr_ext_foreign_toplevel_handle_v1_update_state(v->foreign_list,&state);16
}17
if(v->foreign) {18
wlr_foreign_toplevel_handle_v1_set_title(v->foreign,foreign_title(v));19
wlr_foreign_toplevel_handle_v1_set_app_id(v->foreign,foreign_app_id(v));20
}21
}22
static bool foreign_request_allowed(struct view *v) {23
return v->mapped && !v->server->stopping && !v->server->lock_state;24
}25
static void foreign_request(struct view *v,int request,bool enabled,uint64_t output) {26
if(foreign_request_allowed(v))27
EVENT(127,v->id,request,enabled,output,v->server->lock_generation);28
}29
static void foreign_activate(struct wl_listener *listener,void *data) {30
struct view *v=wl_container_of(listener,v,foreign_activate);31
struct wlr_foreign_toplevel_handle_v1_activated_event *request=data;32
if(request->seat==v->server->seat) foreign_request(v,1,false,0);33
}34
static void foreign_close(struct wl_listener *listener,void *data) {35
(void)data;36
struct view *v=wl_container_of(listener,v,foreign_close);37
foreign_request(v,2,false,0);38
}39
static void foreign_fullscreen(struct wl_listener *listener,void *data) {40
struct view *v=wl_container_of(listener,v,foreign_fullscreen);41
struct wlr_foreign_toplevel_handle_v1_fullscreen_event *request=data;42
if(!foreign_request_allowed(v)) return;43
uint64_t output=0;44
if(request->output) {45
struct output *o;46
wl_list_for_each(o,&v->server->outputs,link)47
if(o->native==request->output) output=o->id;48
if(!output) return;49
}50
foreign_request(v,3,request->fullscreen,output);51
}52
static void foreign_maximize(struct wl_listener *listener,void *data) {53
struct view *v=wl_container_of(listener,v,foreign_maximize);54
struct wlr_foreign_toplevel_handle_v1_maximized_event *request=data;55
foreign_request(v,4,request->maximized,0);56
}57
static void foreign_minimize(struct wl_listener *listener,void *data) {58
struct view *v=wl_container_of(listener,v,foreign_minimize);59
struct wlr_foreign_toplevel_handle_v1_minimized_event *request=data;60
foreign_request(v,5,request->minimized,0);61
}62
static void foreign_outputs(struct view *v) {63
if(!v->foreign) return;64
struct output *o;65
wl_list_for_each(o,&v->server->outputs,link) {66
struct wlr_box box={0},overlap;67
wlr_output_layout_get_box(v->server->layout,o->native,&box);68
bool on=v->foreign_placed && o->configured_enabled &&69
wlr_box_intersection(&overlap,&v->foreign_box,&box);70
if(on) wlr_foreign_toplevel_handle_v1_output_enter(v->foreign,o->native);71
else wlr_foreign_toplevel_handle_v1_output_leave(v->foreign,o->native);72
}73
}74
static void foreign_refresh(struct server *s) {75
struct view *v;76
wl_list_for_each(v,&s->views,link) {77
if(!v->foreign) continue;78
wlr_foreign_toplevel_handle_v1_set_activated(v->foreign,s->focus==v->id);79
foreign_outputs(v);80
}81
}82
static void foreign_map(struct view *v) {83
if(v->layer || (v->x11 && v->x11->override_redirect)) return;84
if(v->server->foreign_list) {85
struct wlr_ext_foreign_toplevel_handle_v1_state state={86
.title=foreign_title(v),.app_id=foreign_app_id(v)};87
v->foreign_list=wlr_ext_foreign_toplevel_handle_v1_create(v->server->foreign_list,&state);88
}89
if(v->server->foreign_manager) {90
v->foreign=wlr_foreign_toplevel_handle_v1_create(v->server->foreign_manager);91
if(v->foreign) {92
listen(&v->foreign->events.request_activate,&v->foreign_activate,foreign_activate);93
listen(&v->foreign->events.request_close,&v->foreign_close,foreign_close);94
listen(&v->foreign->events.request_fullscreen,&v->foreign_fullscreen,foreign_fullscreen);95
listen(&v->foreign->events.request_maximize,&v->foreign_maximize,foreign_maximize);96
listen(&v->foreign->events.request_minimize,&v->foreign_minimize,foreign_minimize);97
}98
}99
foreign_metadata(v);100
}101
static void foreign_unmap(struct view *v) {102
if(v->foreign_list) wlr_ext_foreign_toplevel_handle_v1_destroy(v->foreign_list);103
v->foreign_list=NULL;104
if(v->foreign) {105
wl_list_remove(&v->foreign_activate.link);106
wl_list_remove(&v->foreign_close.link);107
wl_list_remove(&v->foreign_fullscreen.link);108
wl_list_remove(&v->foreign_maximize.link);109
wl_list_remove(&v->foreign_minimize.link);110
wlr_foreign_toplevel_handle_v1_destroy(v->foreign);111
}112
v->foreign=NULL;113
v->foreign_placed=false;114
v->foreign_fullscreen_state=false;115
}116
static void foreign_placement(struct view *v,const int64_t *p) {117
v->foreign_box=(struct wlr_box){p[1],p[2],p[3],p[4]};118
v->foreign_placed=true;119
v->foreign_fullscreen_state=p[7]!=0;120
if(v->foreign)121
wlr_foreign_toplevel_handle_v1_set_fullscreen(v->foreign,v->foreign_fullscreen_state);122
}