mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-18 22:05:48 -05:00
Implement ext-foreign-toplevel-management-v1
This commit is contained in:
parent
e9ae795c2c
commit
1785a50b75
7 changed files with 517 additions and 0 deletions
|
|
@ -67,6 +67,10 @@ struct wlr_ext_foreign_toplevel_info_v1 *wlr_ext_foreign_toplevel_info_v1_create
|
|||
struct wlr_ext_foreign_toplevel_handle_v1 *wlr_ext_foreign_toplevel_handle_v1_create(
|
||||
struct wlr_ext_foreign_toplevel_info_v1 *info);
|
||||
|
||||
// Returns NULL if the toplevel handle is inert
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(struct wl_resource *resource);
|
||||
|
||||
/* Destroy the given toplevel handle, sending the closed event to any
|
||||
* client. Also, if the destroyed toplevel is set as a parent of any
|
||||
* other valid toplevel, clients still holding a handle to both are
|
||||
|
|
|
|||
82
include/wlr/types/wlr_ext_foreign_toplevel_management_v1.h
Normal file
82
include/wlr/types/wlr_ext_foreign_toplevel_management_v1.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||
* future consistency of this API.
|
||||
*/
|
||||
#ifndef WLR_USE_UNSTABLE
|
||||
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||
#endif
|
||||
|
||||
#ifndef WLR_TYPES_WLR_EXT_FOREIGN_TOPLEVEL_MANAGEMENT_V1_H
|
||||
#define WLR_TYPES_WLR_EXT_FOREIGN_TOPLEVEL_MANAGEMENT_V1_H
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_ext_foreign_toplevel_info_v1.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 {
|
||||
struct wl_global *global;
|
||||
|
||||
struct wl_listener display_destroy;
|
||||
|
||||
struct {
|
||||
// wlr_ext_foreign_toplevel_manager_v1_maximize_event
|
||||
struct wl_signal request_maximize;
|
||||
// wlr_ext_foreign_toplevel_manager_v1_minimize_event
|
||||
struct wl_signal request_minimize;
|
||||
// wlr_ext_foreign_toplevel_manager_v1_activate_event
|
||||
struct wl_signal request_activate;
|
||||
// wlr_ext_foreign_toplevel_manager_v1_fullscreen_event
|
||||
struct wl_signal request_fullscreen;
|
||||
// wlr_ext_foreign_toplevel_manager_v1_close_event
|
||||
struct wl_signal request_close;
|
||||
// wlr_ext_foreign_toplevel_manager_v1_set_rectangle_event
|
||||
struct wl_signal set_rectangle;
|
||||
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_maximize_event {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel;
|
||||
bool maximize;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_minimize_event {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel;
|
||||
bool minimize;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_activate_event {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel;
|
||||
struct wlr_seat *seat;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_fullscreen_event {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel;
|
||||
bool fullscreen;
|
||||
struct wlr_output *output;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_close_event {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_set_rectangle_event {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager;
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel;
|
||||
struct wlr_surface *surface;
|
||||
int32_t x, y, width, height;
|
||||
};
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *wlr_ext_foreign_toplevel_manager_v1_create(
|
||||
struct wl_display *display);
|
||||
|
||||
#endif
|
||||
143
protocol/foreign-toplevel-management-unstable-v1.xml
Normal file
143
protocol/foreign-toplevel-management-unstable-v1.xml
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="foreign_toplevel_management_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2018 Ilia Bozhinov
|
||||
Copyright © 2020 Isaac Freund
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zext_foreign_toplevel_manager_v1" version="1">
|
||||
<description summary="control open apps">
|
||||
This protocol allows clients such as a taskbar to request the compositor
|
||||
to preform typical actions on open toplevels. The compositor is in all
|
||||
cases free to ignore the request.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the zext_foreign_toplevel_manager_v1">
|
||||
This request indicates that the client has finished using the
|
||||
zext_foreign_toplevel_manager_v1 object and that it can be safely
|
||||
destroyed.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="close">
|
||||
<description summary="request that a toplevel be closed">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.closed event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="set_maximized">
|
||||
<description summary="request that a toplevel be maximized">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="unset_maximized">
|
||||
<description summary="request that a toplevel be unmaximized">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="set_minimized">
|
||||
<description summary="request that a toplevel be minimized">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="unset_minimized">
|
||||
<description summary="request that a toplevel be unminimized">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="set_fullscreen">
|
||||
<description summary="request that a toplevel be fullscreened">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state and potentially the
|
||||
zext_foreign_toplevel_handle_v1.output_enter/output_leave events will
|
||||
be sent.
|
||||
|
||||
The output parameter a hint to the compositor and may be ignored. A
|
||||
value of NULL indicates that the compositor should choose the target
|
||||
output, if it honors the fullscreen request.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<request name="unset_fullscreen">
|
||||
<description summary="request that a toplevel be unfullscreened">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
</request>
|
||||
|
||||
<request name="activate">
|
||||
<description summary="request that a toplevel be activated">
|
||||
If the compositor honors this request, the
|
||||
zext_foreign_toplevel_handle_v1.state event will be sent.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
<arg name="seat" type="object" interface="wl_seat"/>
|
||||
</request>
|
||||
|
||||
<request name="set_rectangle">
|
||||
<description summary="designate a rectangle to represent a toplevel">
|
||||
If a client using this protocol displays UI elements corresponding
|
||||
to toplevels, it may use this request to inform the server about such
|
||||
a relation. This information may be used by the server, for example as
|
||||
the target for a minimize animation.
|
||||
|
||||
If the client sets more than one rectangle, only the most recently
|
||||
set rectangle is considered.
|
||||
|
||||
The dimensions are given in surface-local coordinates.
|
||||
|
||||
Setting width=height=0 removes the current rectangle if one was set.
|
||||
</description>
|
||||
<arg name="toplevel" type="object" interface="zext_foreign_toplevel_handle_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="x" type="int"/>
|
||||
<arg name="y" type="int"/>
|
||||
<arg name="width" type="int"/>
|
||||
<arg name="height" type="int"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_rectangle" value="0"
|
||||
summary="the provided rectangle is invalid"/>
|
||||
</enum>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
|
@ -45,6 +45,7 @@ protocols = {
|
|||
'wlr-screencopy-unstable-v1': 'wlr-screencopy-unstable-v1.xml',
|
||||
'wlr-virtual-pointer-unstable-v1': 'wlr-virtual-pointer-unstable-v1.xml',
|
||||
'foreign-toplevel-info-unstable-v1': 'foreign-toplevel-info-unstable-v1.xml',
|
||||
'foreign-toplevel-management-unstable-v1': 'foreign-toplevel-management-unstable-v1.xml',
|
||||
}
|
||||
|
||||
protocols_code = {}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ wlr_files += files(
|
|||
'wlr_data_control_v1.c',
|
||||
'wlr_export_dmabuf_v1.c',
|
||||
'wlr_ext_foreign_toplevel_info_v1.c',
|
||||
'wlr_ext_foreign_toplevel_management_v1.c',
|
||||
'wlr_foreign_toplevel_management_v1.c',
|
||||
'wlr_fullscreen_shell_v1.c',
|
||||
'wlr_gamma_control_v1.c',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@
|
|||
|
||||
static const struct zext_foreign_toplevel_handle_v1_interface toplevel_handle_impl;
|
||||
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource,
|
||||
&zext_foreign_toplevel_handle_v1_interface,
|
||||
&toplevel_handle_impl));
|
||||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static void foreign_toplevel_handle_destroy(struct wl_client *client,
|
||||
struct wl_resource *resource) {
|
||||
wl_resource_destroy(resource);
|
||||
|
|
|
|||
278
types/wlr_ext_foreign_toplevel_management_v1.c
Normal file
278
types/wlr_ext_foreign_toplevel_management_v1.c
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/types/wlr_ext_foreign_toplevel_info_v1.h>
|
||||
#include <wlr/types/wlr_ext_foreign_toplevel_management_v1.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_surface.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "util/signal.h"
|
||||
#include "foreign-toplevel-management-unstable-v1-protocol.h"
|
||||
|
||||
#define EXT_FOREIGN_TOPLEVEL_MANAGEMENT_V1_VERSION 1
|
||||
|
||||
static const struct zext_foreign_toplevel_manager_v1_interface manager_impl;
|
||||
|
||||
static struct wlr_ext_foreign_toplevel_manager_v1 *manager_from_resource(
|
||||
struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource,
|
||||
&zext_foreign_toplevel_manager_v1_interface,
|
||||
&manager_impl));
|
||||
return wl_resource_get_user_data(resource);
|
||||
}
|
||||
|
||||
static void manager_emit_maximized_signal(struct wl_resource *resource,
|
||||
struct wl_resource *toplevel_resource, bool state) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(toplevel_resource);
|
||||
if (!toplevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_maximize_event event = {
|
||||
.manager = manager,
|
||||
.toplevel = toplevel,
|
||||
.maximize = state,
|
||||
};
|
||||
wlr_signal_emit_safe(&manager->events.request_maximize, &event);
|
||||
}
|
||||
|
||||
static void manager_handle_set_maximized(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *toplevel_resource) {
|
||||
manager_emit_maximized_signal(resource, toplevel_resource, true);
|
||||
}
|
||||
|
||||
static void manager_handle_unset_maximized(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *toplevel_resource) {
|
||||
manager_emit_maximized_signal(resource, toplevel_resource, false);
|
||||
}
|
||||
|
||||
static void manager_emit_minimized_signal(struct wl_resource *resource,
|
||||
struct wl_resource *toplevel_resource, bool state) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(toplevel_resource);
|
||||
if (!toplevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_minimize_event event = {
|
||||
.manager = manager,
|
||||
.toplevel = toplevel,
|
||||
.minimize = state,
|
||||
};
|
||||
wlr_signal_emit_safe(&manager->events.request_minimize, &event);
|
||||
}
|
||||
|
||||
static void manager_handle_set_minimized(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *toplevel_resource) {
|
||||
manager_emit_minimized_signal(resource, toplevel_resource, true);
|
||||
}
|
||||
|
||||
static void manager_handle_unset_minimized(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *toplevel_resource) {
|
||||
manager_emit_minimized_signal(resource, toplevel_resource, false);
|
||||
}
|
||||
|
||||
static void manager_emit_fullscreen_signal(struct wl_resource *resource,
|
||||
struct wl_resource *toplevel_resource, bool state,
|
||||
struct wl_resource *output_resource) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(toplevel_resource);
|
||||
if (!toplevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_output *output = NULL;
|
||||
if (output_resource) {
|
||||
output = wlr_output_from_resource(output_resource);
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_fullscreen_event event = {
|
||||
.manager = manager,
|
||||
.toplevel = toplevel,
|
||||
.fullscreen = state,
|
||||
.output = output,
|
||||
};
|
||||
wlr_signal_emit_safe(&manager->events.request_fullscreen, &event);
|
||||
}
|
||||
|
||||
static void manager_handle_set_fullscreen(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *toplevel_resource,
|
||||
struct wl_resource *output) {
|
||||
manager_emit_fullscreen_signal(resource, toplevel_resource, true, output);
|
||||
}
|
||||
|
||||
static void manager_handle_unset_fullscreen(struct wl_client *client,
|
||||
struct wl_resource *resource, struct wl_resource *toplevel_resource) {
|
||||
manager_emit_fullscreen_signal(resource, toplevel_resource, false, NULL);
|
||||
}
|
||||
|
||||
static void manager_handle_activate(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *toplevel_resource,
|
||||
struct wl_resource *seat_resource) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(toplevel_resource);
|
||||
if (!toplevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_seat_client *seat_client =
|
||||
wlr_seat_client_from_resource(seat_resource);
|
||||
if (!seat_client) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_activate_event event = {
|
||||
.manager = manager,
|
||||
.toplevel = toplevel,
|
||||
.seat = seat_client->seat,
|
||||
};
|
||||
wlr_signal_emit_safe(&manager->events.request_activate, &event);
|
||||
}
|
||||
|
||||
static void manager_handle_close(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *toplevel_resource) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(toplevel_resource);
|
||||
if (!toplevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_close_event event = {
|
||||
.manager = manager,
|
||||
.toplevel = toplevel,
|
||||
};
|
||||
wlr_signal_emit_safe(&manager->events.request_close, &event);
|
||||
}
|
||||
|
||||
static void manager_handle_set_rectangle(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *toplevel_resource,
|
||||
struct wl_resource *surface_resource,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
manager_from_resource(resource);
|
||||
if (!manager) {
|
||||
return;
|
||||
}
|
||||
struct wlr_ext_foreign_toplevel_handle_v1 *toplevel =
|
||||
wlr_ext_foreign_toplevel_handle_v1_from_resource(toplevel_resource);
|
||||
if (!toplevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
wl_resource_post_error(resource,
|
||||
ZEXT_FOREIGN_TOPLEVEL_MANAGER_V1_ERROR_INVALID_RECTANGLE,
|
||||
"invalid rectangle passed to set_rectangle: width or height < 0");
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1_set_rectangle_event event = {
|
||||
.manager = manager,
|
||||
.toplevel = toplevel,
|
||||
.surface = wlr_surface_from_resource(surface_resource),
|
||||
.x = x,
|
||||
.y = y,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
wlr_signal_emit_safe(&manager->events.set_rectangle, &event);
|
||||
}
|
||||
|
||||
static void manager_handle_destroy(struct wl_client *client,
|
||||
struct wl_resource *resource) {
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
static const struct zext_foreign_toplevel_manager_v1_interface manager_impl = {
|
||||
.set_maximized = manager_handle_set_maximized,
|
||||
.unset_maximized = manager_handle_unset_maximized,
|
||||
.set_minimized = manager_handle_set_minimized,
|
||||
.unset_minimized = manager_handle_unset_minimized,
|
||||
.activate = manager_handle_activate,
|
||||
.close = manager_handle_close,
|
||||
.set_rectangle = manager_handle_set_rectangle,
|
||||
.set_fullscreen = manager_handle_set_fullscreen,
|
||||
.unset_fullscreen = manager_handle_unset_fullscreen,
|
||||
.destroy = manager_handle_destroy,
|
||||
};
|
||||
|
||||
static void manager_bind(struct wl_client *client, void *data,
|
||||
uint32_t version, uint32_t id) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager = data;
|
||||
struct wl_resource *resource = wl_resource_create(client,
|
||||
&zext_foreign_toplevel_manager_v1_interface, version, id);
|
||||
if (!resource) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(resource, &manager_impl, manager, NULL);
|
||||
}
|
||||
|
||||
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager =
|
||||
wl_container_of(listener, manager, display_destroy);
|
||||
wlr_signal_emit_safe(&manager->events.destroy, manager);
|
||||
wl_list_remove(&manager->display_destroy.link);
|
||||
wl_global_destroy(manager->global);
|
||||
free(manager);
|
||||
}
|
||||
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *wlr_ext_foreign_toplevel_manager_v1_create(
|
||||
struct wl_display *display) {
|
||||
struct wlr_ext_foreign_toplevel_manager_v1 *manager = calloc(1,
|
||||
sizeof(struct wlr_ext_foreign_toplevel_manager_v1));
|
||||
if (!manager) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
manager->global = wl_global_create(display,
|
||||
&zext_foreign_toplevel_manager_v1_interface,
|
||||
EXT_FOREIGN_TOPLEVEL_MANAGEMENT_V1_VERSION, manager,
|
||||
manager_bind);
|
||||
if (!manager->global) {
|
||||
free(manager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_signal_init(&manager->events.request_maximize);
|
||||
wl_signal_init(&manager->events.request_minimize);
|
||||
wl_signal_init(&manager->events.request_activate);
|
||||
wl_signal_init(&manager->events.request_fullscreen);
|
||||
wl_signal_init(&manager->events.request_close);
|
||||
wl_signal_init(&manager->events.set_rectangle);
|
||||
wl_signal_init(&manager->events.destroy);
|
||||
|
||||
manager->display_destroy.notify = handle_display_destroy;
|
||||
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||
|
||||
return manager;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue