// Generated by go-wayland-scanner
// https://github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/cmd/go-wayland-scanner
// XML file : ext-workspace-v1.xml
//
// ext_workspace_v1 Protocol Copyright:
//
// Copyright © 2019 Christopher Billington
// Copyright © 2020 Ilia Bozhinov
// Copyright © 2022 Victoria Brekenfeld
//
// 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.

package ext_workspace

import (
	"reflect"
	"unsafe"

	"github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
	"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
)

// registerServerProxy registers a proxy with a server-assigned ID.
// This is necessary because go-wayland-scanner doesn't properly handle new_id arguments in events.
// In requests (like DWL), the client creates the ID via NewXxx(ctx) which calls ctx.Register().
// In events (like ext-workspace), the server creates the ID and sends it, requiring manual registration.
// The Context.objects map is private with no public API for server IDs, requiring reflection.
func registerServerProxy(ctx *client.Context, proxy client.Proxy, serverID uint32) {
	defer func() {
		if r := recover(); r != nil {
			return
		}
	}()

	ctxVal := reflect.ValueOf(ctx)
	if ctxVal.Kind() != reflect.Ptr || ctxVal.IsNil() {
		return
	}

	ctxElem := ctxVal.Elem()
	objectsField := ctxElem.FieldByName("objects")
	if !objectsField.IsValid() {
		return
	}

	objectsMapPtr := unsafe.Pointer(objectsField.UnsafeAddr())
	objectsMap := (*syncmap.Map[uint32, client.Proxy])(objectsMapPtr)
	objectsMap.Store(serverID, proxy)
}

// ExtWorkspaceManagerV1InterfaceName is the name of the interface as it appears in the [client.Registry].
// It can be used to match the [client.RegistryGlobalEvent.Interface] in the
// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies.
const ExtWorkspaceManagerV1InterfaceName = "ext_workspace_manager_v1"

// ExtWorkspaceManagerV1 : list and control workspaces
//
// Workspaces, also called virtual desktops, are groups of surfaces. A
// compositor with a concept of workspaces may only show some such groups of
// surfaces (those of 'active' workspaces) at a time. 'Activating' a
// workspace is a request for the compositor to display that workspace's
// surfaces as normal, whereas the compositor may hide or otherwise
// de-emphasise surfaces that are associated only with 'inactive' workspaces.
// Workspaces are grouped by which sets of outputs they correspond to, and
// may contain surfaces only from those outputs. In this way, it is possible
// for each output to have its own set of workspaces, or for all outputs (or
// any other arbitrary grouping) to share workspaces. Compositors may
// optionally conceptually arrange each group of workspaces in an
// N-dimensional grid.
//
// The purpose of this protocol is to enable the creation of taskbars and
// docks by providing them with a list of workspaces and their properties,
// and allowing them to activate and deactivate workspaces.
//
// After a client binds the ext_workspace_manager_v1, each workspace will be
// sent via the workspace event.
type ExtWorkspaceManagerV1 struct {
	client.BaseProxy
	workspaceGroupHandler ExtWorkspaceManagerV1WorkspaceGroupHandlerFunc
	workspaceHandler      ExtWorkspaceManagerV1WorkspaceHandlerFunc
	doneHandler           ExtWorkspaceManagerV1DoneHandlerFunc
	finishedHandler       ExtWorkspaceManagerV1FinishedHandlerFunc
}

// NewExtWorkspaceManagerV1 : list and control workspaces
//
// Workspaces, also called virtual desktops, are groups of surfaces. A
// compositor with a concept of workspaces may only show some such groups of
// surfaces (those of 'active' workspaces) at a time. 'Activating' a
// workspace is a request for the compositor to display that workspace's
// surfaces as normal, whereas the compositor may hide or otherwise
// de-emphasise surfaces that are associated only with 'inactive' workspaces.
// Workspaces are grouped by which sets of outputs they correspond to, and
// may contain surfaces only from those outputs. In this way, it is possible
// for each output to have its own set of workspaces, or for all outputs (or
// any other arbitrary grouping) to share workspaces. Compositors may
// optionally conceptually arrange each group of workspaces in an
// N-dimensional grid.
//
// The purpose of this protocol is to enable the creation of taskbars and
// docks by providing them with a list of workspaces and their properties,
// and allowing them to activate and deactivate workspaces.
//
// After a client binds the ext_workspace_manager_v1, each workspace will be
// sent via the workspace event.
func NewExtWorkspaceManagerV1(ctx *client.Context) *ExtWorkspaceManagerV1 {
	extWorkspaceManagerV1 := &ExtWorkspaceManagerV1{}
	ctx.Register(extWorkspaceManagerV1)
	return extWorkspaceManagerV1
}

// Commit : all requests about the workspaces have been sent
//
// The client must send this request after it has finished sending other
// requests. The compositor must process a series of requests preceding a
// commit request atomically.
//
// This allows changes to the workspace properties to be seen as atomic,
// even if they happen via multiple events, and even if they involve
// multiple ext_workspace_handle_v1 objects, for example, deactivating one
// workspace and activating another.
func (i *ExtWorkspaceManagerV1) Commit() error {
	const opcode = 0
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

// Stop : stop sending events
//
// Indicates the client no longer wishes to receive events for new
// workspace groups. However the compositor may emit further workspace
// events, until the finished event is emitted. The compositor is expected
// to send the finished event eventually once the stop request has been processed.
//
// The client must not send any requests after this one, doing so will raise a wl_display
// invalid_object error.
func (i *ExtWorkspaceManagerV1) Stop() error {
	const opcode = 1
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

func (i *ExtWorkspaceManagerV1) Destroy() error {
	i.MarkZombie()
	return nil
}

// ExtWorkspaceManagerV1WorkspaceGroupEvent : a workspace group has been created
//
// This event is emitted whenever a new workspace group has been created.
//
// All initial details of the workspace group (outputs) will be
// sent immediately after this event via the corresponding events in
// ext_workspace_group_handle_v1 and ext_workspace_handle_v1.
type ExtWorkspaceManagerV1WorkspaceGroupEvent struct {
	WorkspaceGroup *ExtWorkspaceGroupHandleV1
}
type ExtWorkspaceManagerV1WorkspaceGroupHandlerFunc func(ExtWorkspaceManagerV1WorkspaceGroupEvent)

// SetWorkspaceGroupHandler : sets handler for ExtWorkspaceManagerV1WorkspaceGroupEvent
func (i *ExtWorkspaceManagerV1) SetWorkspaceGroupHandler(f ExtWorkspaceManagerV1WorkspaceGroupHandlerFunc) {
	i.workspaceGroupHandler = f
}

// ExtWorkspaceManagerV1WorkspaceEvent : workspace has been created
//
// This event is emitted whenever a new workspace has been created.
//
// All initial details of the workspace (name, coordinates, state) will
// be sent immediately after this event via the corresponding events in
// ext_workspace_handle_v1.
//
// Workspaces start off unassigned to any workspace group.
type ExtWorkspaceManagerV1WorkspaceEvent struct {
	Workspace *ExtWorkspaceHandleV1
}
type ExtWorkspaceManagerV1WorkspaceHandlerFunc func(ExtWorkspaceManagerV1WorkspaceEvent)

// SetWorkspaceHandler : sets handler for ExtWorkspaceManagerV1WorkspaceEvent
func (i *ExtWorkspaceManagerV1) SetWorkspaceHandler(f ExtWorkspaceManagerV1WorkspaceHandlerFunc) {
	i.workspaceHandler = f
}

// ExtWorkspaceManagerV1DoneEvent : all information about the workspaces and workspace groups has been sent
//
// This event is sent after all changes in all workspaces and workspace groups have been
// sent.
//
// This allows changes to one or more ext_workspace_group_handle_v1
// properties and ext_workspace_handle_v1 properties
// to be seen as atomic, even if they happen via multiple events.
// In particular, an output moving from one workspace group to
// another sends an output_enter event and an output_leave event to the two
// ext_workspace_group_handle_v1 objects in question. The compositor sends
// the done event only after updating the output information in both
// workspace groups.
type ExtWorkspaceManagerV1DoneEvent struct{}
type ExtWorkspaceManagerV1DoneHandlerFunc func(ExtWorkspaceManagerV1DoneEvent)

// SetDoneHandler : sets handler for ExtWorkspaceManagerV1DoneEvent
func (i *ExtWorkspaceManagerV1) SetDoneHandler(f ExtWorkspaceManagerV1DoneHandlerFunc) {
	i.doneHandler = f
}

// ExtWorkspaceManagerV1FinishedEvent : the compositor has finished with the workspace_manager
//
// This event indicates that the compositor is done sending events to the
// ext_workspace_manager_v1. The server will destroy the object
// immediately after sending this request.
type ExtWorkspaceManagerV1FinishedEvent struct{}
type ExtWorkspaceManagerV1FinishedHandlerFunc func(ExtWorkspaceManagerV1FinishedEvent)

// SetFinishedHandler : sets handler for ExtWorkspaceManagerV1FinishedEvent
func (i *ExtWorkspaceManagerV1) SetFinishedHandler(f ExtWorkspaceManagerV1FinishedHandlerFunc) {
	i.finishedHandler = f
}

func (i *ExtWorkspaceManagerV1) Dispatch(opcode uint32, fd int, data []byte) {
	switch opcode {
	case 0:
		if i.workspaceGroupHandler == nil {
			return
		}
		var e ExtWorkspaceManagerV1WorkspaceGroupEvent
		l := 0
		objectID := client.Uint32(data[l : l+4])
		proxy := i.Context().GetProxy(objectID)
		if proxy != nil && !proxy.IsZombie() {
			e.WorkspaceGroup = proxy.(*ExtWorkspaceGroupHandleV1)
		} else {
			groupHandle := &ExtWorkspaceGroupHandleV1{}
			groupHandle.SetContext(i.Context())
			groupHandle.SetID(objectID)
			registerServerProxy(i.Context(), groupHandle, objectID)
			e.WorkspaceGroup = groupHandle
		}
		l += 4

		i.workspaceGroupHandler(e)
	case 1:
		if i.workspaceHandler == nil {
			return
		}
		var e ExtWorkspaceManagerV1WorkspaceEvent
		l := 0
		objectID := client.Uint32(data[l : l+4])
		proxy := i.Context().GetProxy(objectID)
		if proxy != nil && !proxy.IsZombie() {
			e.Workspace = proxy.(*ExtWorkspaceHandleV1)
		} else {
			wsHandle := &ExtWorkspaceHandleV1{}
			wsHandle.SetContext(i.Context())
			wsHandle.SetID(objectID)
			registerServerProxy(i.Context(), wsHandle, objectID)
			e.Workspace = wsHandle
		}
		l += 4

		i.workspaceHandler(e)
	case 2:
		if i.doneHandler == nil {
			return
		}
		var e ExtWorkspaceManagerV1DoneEvent

		i.doneHandler(e)
	case 3:
		if i.finishedHandler == nil {
			return
		}
		var e ExtWorkspaceManagerV1FinishedEvent

		i.finishedHandler(e)
	}
}

// ExtWorkspaceGroupHandleV1InterfaceName is the name of the interface as it appears in the [client.Registry].
// It can be used to match the [client.RegistryGlobalEvent.Interface] in the
// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies.
const ExtWorkspaceGroupHandleV1InterfaceName = "ext_workspace_group_handle_v1"

// ExtWorkspaceGroupHandleV1 : a workspace group assigned to a set of outputs
//
// A ext_workspace_group_handle_v1 object represents a workspace group
// that is assigned a set of outputs and contains a number of workspaces.
//
// The set of outputs assigned to the workspace group is conveyed to the client via
// output_enter and output_leave events, and its workspaces are conveyed with
// workspace events.
//
// For example, a compositor which has a set of workspaces for each output may
// advertise a workspace group (and its workspaces) per output, whereas a compositor
// where a workspace spans all outputs may advertise a single workspace group for all
// outputs.
type ExtWorkspaceGroupHandleV1 struct {
	client.BaseProxy
	capabilitiesHandler   ExtWorkspaceGroupHandleV1CapabilitiesHandlerFunc
	outputEnterHandler    ExtWorkspaceGroupHandleV1OutputEnterHandlerFunc
	outputLeaveHandler    ExtWorkspaceGroupHandleV1OutputLeaveHandlerFunc
	workspaceEnterHandler ExtWorkspaceGroupHandleV1WorkspaceEnterHandlerFunc
	workspaceLeaveHandler ExtWorkspaceGroupHandleV1WorkspaceLeaveHandlerFunc
	removedHandler        ExtWorkspaceGroupHandleV1RemovedHandlerFunc
}

// NewExtWorkspaceGroupHandleV1 : a workspace group assigned to a set of outputs
//
// A ext_workspace_group_handle_v1 object represents a workspace group
// that is assigned a set of outputs and contains a number of workspaces.
//
// The set of outputs assigned to the workspace group is conveyed to the client via
// output_enter and output_leave events, and its workspaces are conveyed with
// workspace events.
//
// For example, a compositor which has a set of workspaces for each output may
// advertise a workspace group (and its workspaces) per output, whereas a compositor
// where a workspace spans all outputs may advertise a single workspace group for all
// outputs.
func NewExtWorkspaceGroupHandleV1(ctx *client.Context) *ExtWorkspaceGroupHandleV1 {
	extWorkspaceGroupHandleV1 := &ExtWorkspaceGroupHandleV1{}
	ctx.Register(extWorkspaceGroupHandleV1)
	return extWorkspaceGroupHandleV1
}

// CreateWorkspace : create a new workspace
//
// Request that the compositor create a new workspace with the given name
// and assign it to this group.
//
// There is no guarantee that the compositor will create a new workspace,
// or that the created workspace will have the provided name.
func (i *ExtWorkspaceGroupHandleV1) CreateWorkspace(workspace string) error {
	const opcode = 0
	workspaceLen := client.PaddedLen(len(workspace) + 1)
	_reqBufLen := 8 + (4 + workspaceLen)
	_reqBuf := make([]byte, _reqBufLen)
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	client.PutString(_reqBuf[l:l+(4+workspaceLen)], workspace)
	l += (4 + workspaceLen)
	err := i.Context().WriteMsg(_reqBuf, nil)
	return err
}

// Destroy : destroy the ext_workspace_group_handle_v1 object
//
// Destroys the ext_workspace_group_handle_v1 object.
//
// This request should be send either when the client does not want to
// use the workspace group object any more or after the removed event to finalize
// the destruction of the object.
func (i *ExtWorkspaceGroupHandleV1) Destroy() error {
	defer i.MarkZombie()
	const opcode = 1
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

type ExtWorkspaceGroupHandleV1GroupCapabilities uint32

// ExtWorkspaceGroupHandleV1GroupCapabilities :
const (
	// ExtWorkspaceGroupHandleV1GroupCapabilitiesCreateWorkspace : create_workspace request is available
	ExtWorkspaceGroupHandleV1GroupCapabilitiesCreateWorkspace ExtWorkspaceGroupHandleV1GroupCapabilities = 1
)

func (e ExtWorkspaceGroupHandleV1GroupCapabilities) Name() string {
	switch e {
	case ExtWorkspaceGroupHandleV1GroupCapabilitiesCreateWorkspace:
		return "create_workspace"
	default:
		return ""
	}
}

func (e ExtWorkspaceGroupHandleV1GroupCapabilities) Value() string {
	switch e {
	case ExtWorkspaceGroupHandleV1GroupCapabilitiesCreateWorkspace:
		return "1"
	default:
		return ""
	}
}

func (e ExtWorkspaceGroupHandleV1GroupCapabilities) String() string {
	return e.Name() + "=" + e.Value()
}

// ExtWorkspaceGroupHandleV1CapabilitiesEvent : compositor capabilities
//
// This event advertises the capabilities supported by the compositor. If
// a capability isn't supported, clients should hide or disable the UI
// elements that expose this functionality. For instance, if the
// compositor doesn't advertise support for creating workspaces, a button
// triggering the create_workspace request should not be displayed.
//
// The compositor will ignore requests it doesn't support. For instance,
// a compositor which doesn't advertise support for creating workspaces will ignore
// create_workspace requests.
//
// Compositors must send this event once after creation of an
// ext_workspace_group_handle_v1. When the capabilities change, compositors
// must send this event again.
type ExtWorkspaceGroupHandleV1CapabilitiesEvent struct {
	Capabilities uint32
}
type ExtWorkspaceGroupHandleV1CapabilitiesHandlerFunc func(ExtWorkspaceGroupHandleV1CapabilitiesEvent)

// SetCapabilitiesHandler : sets handler for ExtWorkspaceGroupHandleV1CapabilitiesEvent
func (i *ExtWorkspaceGroupHandleV1) SetCapabilitiesHandler(f ExtWorkspaceGroupHandleV1CapabilitiesHandlerFunc) {
	i.capabilitiesHandler = f
}

// ExtWorkspaceGroupHandleV1OutputEnterEvent : output assigned to workspace group
//
// This event is emitted whenever an output is assigned to the workspace
// group or a new `wl_output` object is bound by the client, which was already
// assigned to this workspace_group.
type ExtWorkspaceGroupHandleV1OutputEnterEvent struct {
	Output *client.Output
}
type ExtWorkspaceGroupHandleV1OutputEnterHandlerFunc func(ExtWorkspaceGroupHandleV1OutputEnterEvent)

// SetOutputEnterHandler : sets handler for ExtWorkspaceGroupHandleV1OutputEnterEvent
func (i *ExtWorkspaceGroupHandleV1) SetOutputEnterHandler(f ExtWorkspaceGroupHandleV1OutputEnterHandlerFunc) {
	i.outputEnterHandler = f
}

// ExtWorkspaceGroupHandleV1OutputLeaveEvent : output removed from workspace group
//
// This event is emitted whenever an output is removed from the workspace
// group.
type ExtWorkspaceGroupHandleV1OutputLeaveEvent struct {
	Output *client.Output
}
type ExtWorkspaceGroupHandleV1OutputLeaveHandlerFunc func(ExtWorkspaceGroupHandleV1OutputLeaveEvent)

// SetOutputLeaveHandler : sets handler for ExtWorkspaceGroupHandleV1OutputLeaveEvent
func (i *ExtWorkspaceGroupHandleV1) SetOutputLeaveHandler(f ExtWorkspaceGroupHandleV1OutputLeaveHandlerFunc) {
	i.outputLeaveHandler = f
}

// ExtWorkspaceGroupHandleV1WorkspaceEnterEvent : workspace added to workspace group
//
// This event is emitted whenever a workspace is assigned to this group.
// A workspace may only ever be assigned to a single group at a single point
// in time, but can be re-assigned during it's lifetime.
type ExtWorkspaceGroupHandleV1WorkspaceEnterEvent struct {
	Workspace *ExtWorkspaceHandleV1
}
type ExtWorkspaceGroupHandleV1WorkspaceEnterHandlerFunc func(ExtWorkspaceGroupHandleV1WorkspaceEnterEvent)

// SetWorkspaceEnterHandler : sets handler for ExtWorkspaceGroupHandleV1WorkspaceEnterEvent
func (i *ExtWorkspaceGroupHandleV1) SetWorkspaceEnterHandler(f ExtWorkspaceGroupHandleV1WorkspaceEnterHandlerFunc) {
	i.workspaceEnterHandler = f
}

// ExtWorkspaceGroupHandleV1WorkspaceLeaveEvent : workspace removed from workspace group
//
// This event is emitted whenever a workspace is removed from this group.
type ExtWorkspaceGroupHandleV1WorkspaceLeaveEvent struct {
	Workspace *ExtWorkspaceHandleV1
}
type ExtWorkspaceGroupHandleV1WorkspaceLeaveHandlerFunc func(ExtWorkspaceGroupHandleV1WorkspaceLeaveEvent)

// SetWorkspaceLeaveHandler : sets handler for ExtWorkspaceGroupHandleV1WorkspaceLeaveEvent
func (i *ExtWorkspaceGroupHandleV1) SetWorkspaceLeaveHandler(f ExtWorkspaceGroupHandleV1WorkspaceLeaveHandlerFunc) {
	i.workspaceLeaveHandler = f
}

// ExtWorkspaceGroupHandleV1RemovedEvent : this workspace group has been removed
//
// This event is send when the group associated with the ext_workspace_group_handle_v1
// has been removed. After sending this request the compositor will immediately consider
// the object inert. Any requests will be ignored except the destroy request.
// It is guaranteed there won't be any more events referencing this
// ext_workspace_group_handle_v1.
//
// The compositor must remove all workspaces belonging to a workspace group
// via a workspace_leave event before removing the workspace group.
type ExtWorkspaceGroupHandleV1RemovedEvent struct{}
type ExtWorkspaceGroupHandleV1RemovedHandlerFunc func(ExtWorkspaceGroupHandleV1RemovedEvent)

// SetRemovedHandler : sets handler for ExtWorkspaceGroupHandleV1RemovedEvent
func (i *ExtWorkspaceGroupHandleV1) SetRemovedHandler(f ExtWorkspaceGroupHandleV1RemovedHandlerFunc) {
	i.removedHandler = f
}

func (i *ExtWorkspaceGroupHandleV1) Dispatch(opcode uint32, fd int, data []byte) {
	switch opcode {
	case 0:
		if i.capabilitiesHandler == nil {
			return
		}
		var e ExtWorkspaceGroupHandleV1CapabilitiesEvent
		l := 0
		e.Capabilities = client.Uint32(data[l : l+4])
		l += 4

		i.capabilitiesHandler(e)
	case 1:
		if i.outputEnterHandler == nil {
			return
		}
		var e ExtWorkspaceGroupHandleV1OutputEnterEvent
		l := 0
		e.Output = i.Context().GetProxy(client.Uint32(data[l : l+4])).(*client.Output)
		l += 4

		i.outputEnterHandler(e)
	case 2:
		if i.outputLeaveHandler == nil {
			return
		}
		var e ExtWorkspaceGroupHandleV1OutputLeaveEvent
		l := 0
		e.Output = i.Context().GetProxy(client.Uint32(data[l : l+4])).(*client.Output)
		l += 4

		i.outputLeaveHandler(e)
	case 3:
		if i.workspaceEnterHandler == nil {
			return
		}
		var e ExtWorkspaceGroupHandleV1WorkspaceEnterEvent
		l := 0
		e.Workspace = i.Context().GetProxy(client.Uint32(data[l : l+4])).(*ExtWorkspaceHandleV1)
		l += 4

		i.workspaceEnterHandler(e)
	case 4:
		if i.workspaceLeaveHandler == nil {
			return
		}
		var e ExtWorkspaceGroupHandleV1WorkspaceLeaveEvent
		l := 0
		e.Workspace = i.Context().GetProxy(client.Uint32(data[l : l+4])).(*ExtWorkspaceHandleV1)
		l += 4

		i.workspaceLeaveHandler(e)
	case 5:
		if i.removedHandler == nil {
			return
		}
		var e ExtWorkspaceGroupHandleV1RemovedEvent

		i.removedHandler(e)
	}
}

// ExtWorkspaceHandleV1InterfaceName is the name of the interface as it appears in the [client.Registry].
// It can be used to match the [client.RegistryGlobalEvent.Interface] in the
// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies.
const ExtWorkspaceHandleV1InterfaceName = "ext_workspace_handle_v1"

// ExtWorkspaceHandleV1 : a workspace handing a group of surfaces
//
// A ext_workspace_handle_v1 object represents a workspace that handles a
// group of surfaces.
//
// Each workspace has:
// - a name, conveyed to the client with the name event
// - potentially an id conveyed with the id event
// - a list of states, conveyed to the client with the state event
// - and optionally a set of coordinates, conveyed to the client with the
// coordinates event
//
// The client may request that the compositor activate or deactivate the workspace.
//
// Each workspace can belong to only a single workspace group.
// Depending on the compositor policy, there might be workspaces with
// the same name in different workspace groups, but these workspaces are still
// separate (e.g. one of them might be active while the other is not).
type ExtWorkspaceHandleV1 struct {
	client.BaseProxy
	idHandler           ExtWorkspaceHandleV1IdHandlerFunc
	nameHandler         ExtWorkspaceHandleV1NameHandlerFunc
	coordinatesHandler  ExtWorkspaceHandleV1CoordinatesHandlerFunc
	stateHandler        ExtWorkspaceHandleV1StateHandlerFunc
	capabilitiesHandler ExtWorkspaceHandleV1CapabilitiesHandlerFunc
	removedHandler      ExtWorkspaceHandleV1RemovedHandlerFunc
}

// NewExtWorkspaceHandleV1 : a workspace handing a group of surfaces
//
// A ext_workspace_handle_v1 object represents a workspace that handles a
// group of surfaces.
//
// Each workspace has:
// - a name, conveyed to the client with the name event
// - potentially an id conveyed with the id event
// - a list of states, conveyed to the client with the state event
// - and optionally a set of coordinates, conveyed to the client with the
// coordinates event
//
// The client may request that the compositor activate or deactivate the workspace.
//
// Each workspace can belong to only a single workspace group.
// Depending on the compositor policy, there might be workspaces with
// the same name in different workspace groups, but these workspaces are still
// separate (e.g. one of them might be active while the other is not).
func NewExtWorkspaceHandleV1(ctx *client.Context) *ExtWorkspaceHandleV1 {
	extWorkspaceHandleV1 := &ExtWorkspaceHandleV1{}
	ctx.Register(extWorkspaceHandleV1)
	return extWorkspaceHandleV1
}

// Destroy : destroy the ext_workspace_handle_v1 object
//
// Destroys the ext_workspace_handle_v1 object.
//
// This request should be made either when the client does not want to
// use the workspace object any more or after the remove event to finalize
// the destruction of the object.
func (i *ExtWorkspaceHandleV1) Destroy() error {
	defer i.MarkZombie()
	const opcode = 0
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

// Activate : activate the workspace
//
// Request that this workspace be activated.
//
// There is no guarantee the workspace will be actually activated, and
// behaviour may be compositor-dependent. For example, activating a
// workspace may or may not deactivate all other workspaces in the same
// group.
func (i *ExtWorkspaceHandleV1) Activate() error {
	const opcode = 1
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

// Deactivate : deactivate the workspace
//
// Request that this workspace be deactivated.
//
// There is no guarantee the workspace will be actually deactivated.
func (i *ExtWorkspaceHandleV1) Deactivate() error {
	const opcode = 2
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

// Assign : assign workspace to group
//
// Requests that this workspace is assigned to the given workspace group.
//
// There is no guarantee the workspace will be assigned.
func (i *ExtWorkspaceHandleV1) Assign(workspaceGroup *ExtWorkspaceGroupHandleV1) error {
	const opcode = 3
	const _reqBufLen = 8 + 4
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	client.PutUint32(_reqBuf[l:l+4], workspaceGroup.ID())
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

// Remove : remove the workspace
//
// Request that this workspace be removed.
//
// There is no guarantee the workspace will be actually removed.
func (i *ExtWorkspaceHandleV1) Remove() error {
	const opcode = 4
	const _reqBufLen = 8
	var _reqBuf [_reqBufLen]byte
	l := 0
	client.PutUint32(_reqBuf[l:4], i.ID())
	l += 4
	client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
	l += 4
	err := i.Context().WriteMsg(_reqBuf[:], nil)
	return err
}

type ExtWorkspaceHandleV1State uint32

// ExtWorkspaceHandleV1State : types of states on the workspace
//
// The different states that a workspace can have.
const (
	// ExtWorkspaceHandleV1StateActive : the workspace is active
	ExtWorkspaceHandleV1StateActive ExtWorkspaceHandleV1State = 1
	// ExtWorkspaceHandleV1StateUrgent : the workspace requests attention
	ExtWorkspaceHandleV1StateUrgent ExtWorkspaceHandleV1State = 2
	ExtWorkspaceHandleV1StateHidden ExtWorkspaceHandleV1State = 4
)

func (e ExtWorkspaceHandleV1State) Name() string {
	switch e {
	case ExtWorkspaceHandleV1StateActive:
		return "active"
	case ExtWorkspaceHandleV1StateUrgent:
		return "urgent"
	case ExtWorkspaceHandleV1StateHidden:
		return "hidden"
	default:
		return ""
	}
}

func (e ExtWorkspaceHandleV1State) Value() string {
	switch e {
	case ExtWorkspaceHandleV1StateActive:
		return "1"
	case ExtWorkspaceHandleV1StateUrgent:
		return "2"
	case ExtWorkspaceHandleV1StateHidden:
		return "4"
	default:
		return ""
	}
}

func (e ExtWorkspaceHandleV1State) String() string {
	return e.Name() + "=" + e.Value()
}

type ExtWorkspaceHandleV1WorkspaceCapabilities uint32

// ExtWorkspaceHandleV1WorkspaceCapabilities :
const (
	// ExtWorkspaceHandleV1WorkspaceCapabilitiesActivate : activate request is available
	ExtWorkspaceHandleV1WorkspaceCapabilitiesActivate ExtWorkspaceHandleV1WorkspaceCapabilities = 1
	// ExtWorkspaceHandleV1WorkspaceCapabilitiesDeactivate : deactivate request is available
	ExtWorkspaceHandleV1WorkspaceCapabilitiesDeactivate ExtWorkspaceHandleV1WorkspaceCapabilities = 2
	// ExtWorkspaceHandleV1WorkspaceCapabilitiesRemove : remove request is available
	ExtWorkspaceHandleV1WorkspaceCapabilitiesRemove ExtWorkspaceHandleV1WorkspaceCapabilities = 4
	// ExtWorkspaceHandleV1WorkspaceCapabilitiesAssign : assign request is available
	ExtWorkspaceHandleV1WorkspaceCapabilitiesAssign ExtWorkspaceHandleV1WorkspaceCapabilities = 8
)

func (e ExtWorkspaceHandleV1WorkspaceCapabilities) Name() string {
	switch e {
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesActivate:
		return "activate"
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesDeactivate:
		return "deactivate"
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesRemove:
		return "remove"
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesAssign:
		return "assign"
	default:
		return ""
	}
}

func (e ExtWorkspaceHandleV1WorkspaceCapabilities) Value() string {
	switch e {
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesActivate:
		return "1"
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesDeactivate:
		return "2"
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesRemove:
		return "4"
	case ExtWorkspaceHandleV1WorkspaceCapabilitiesAssign:
		return "8"
	default:
		return ""
	}
}

func (e ExtWorkspaceHandleV1WorkspaceCapabilities) String() string {
	return e.Name() + "=" + e.Value()
}

// ExtWorkspaceHandleV1IdEvent : workspace id
//
// If this event is emitted, it will be send immediately after the
// ext_workspace_handle_v1 is created or when an id is assigned to
// a workspace (at most once during it's lifetime).
//
// An id will never change during the lifetime of the `ext_workspace_handle_v1`
// and is guaranteed to be unique during it's lifetime.
//
// Ids are not human-readable and shouldn't be displayed, use `name` for that purpose.
//
// Compositors are expected to only send ids for workspaces likely stable across multiple
// sessions and can be used by clients to store preferences for workspaces. Workspaces without
// ids should be considered temporary and any data associated with them should be deleted once
// the respective object is lost.
type ExtWorkspaceHandleV1IdEvent struct {
	Id string
}
type ExtWorkspaceHandleV1IdHandlerFunc func(ExtWorkspaceHandleV1IdEvent)

// SetIdHandler : sets handler for ExtWorkspaceHandleV1IdEvent
func (i *ExtWorkspaceHandleV1) SetIdHandler(f ExtWorkspaceHandleV1IdHandlerFunc) {
	i.idHandler = f
}

// ExtWorkspaceHandleV1NameEvent : workspace name changed
//
// This event is emitted immediately after the ext_workspace_handle_v1 is
// created and whenever the name of the workspace changes.
//
// A name is meant to be human-readable and can be displayed to a user.
// Unlike the id it is neither stable nor unique.
type ExtWorkspaceHandleV1NameEvent struct {
	Name string
}
type ExtWorkspaceHandleV1NameHandlerFunc func(ExtWorkspaceHandleV1NameEvent)

// SetNameHandler : sets handler for ExtWorkspaceHandleV1NameEvent
func (i *ExtWorkspaceHandleV1) SetNameHandler(f ExtWorkspaceHandleV1NameHandlerFunc) {
	i.nameHandler = f
}

// ExtWorkspaceHandleV1CoordinatesEvent : workspace coordinates changed
//
// This event is used to organize workspaces into an N-dimensional grid
// within a workspace group, and if supported, is emitted immediately after
// the ext_workspace_handle_v1 is created and whenever the coordinates of
// the workspace change. Compositors may not send this event if they do not
// conceptually arrange workspaces in this way. If compositors simply
// number workspaces, without any geometric interpretation, they may send
// 1D coordinates, which clients should not interpret as implying any
// geometry. Sending an empty array means that the compositor no longer
// orders the workspace geometrically.
//
// Coordinates have an arbitrary number of dimensions N with an uint32
// position along each dimension. By convention if N > 1, the first
// dimension is X, the second Y, the third Z, and so on. The compositor may
// chose to utilize these events for a more novel workspace layout
// convention, however. No guarantee is made about the grid being filled or
// bounded; there may be a workspace at coordinate 1 and another at
// coordinate 1000 and none in between. Within a workspace group, however,
// workspaces must have unique coordinates of equal dimensionality.
type ExtWorkspaceHandleV1CoordinatesEvent struct {
	Coordinates []byte
}
type ExtWorkspaceHandleV1CoordinatesHandlerFunc func(ExtWorkspaceHandleV1CoordinatesEvent)

// SetCoordinatesHandler : sets handler for ExtWorkspaceHandleV1CoordinatesEvent
func (i *ExtWorkspaceHandleV1) SetCoordinatesHandler(f ExtWorkspaceHandleV1CoordinatesHandlerFunc) {
	i.coordinatesHandler = f
}

// ExtWorkspaceHandleV1StateEvent : the state of the workspace changed
//
// This event is emitted immediately after the ext_workspace_handle_v1 is
// created and each time the workspace state changes, either because of a
// compositor action or because of a request in this protocol.
//
// Missing states convey the opposite meaning, e.g. an unset active bit
// means the workspace is currently inactive.
type ExtWorkspaceHandleV1StateEvent struct {
	State uint32
}
type ExtWorkspaceHandleV1StateHandlerFunc func(ExtWorkspaceHandleV1StateEvent)

// SetStateHandler : sets handler for ExtWorkspaceHandleV1StateEvent
func (i *ExtWorkspaceHandleV1) SetStateHandler(f ExtWorkspaceHandleV1StateHandlerFunc) {
	i.stateHandler = f
}

// ExtWorkspaceHandleV1CapabilitiesEvent : compositor capabilities
//
// This event advertises the capabilities supported by the compositor. If
// a capability isn't supported, clients should hide or disable the UI
// elements that expose this functionality. For instance, if the
// compositor doesn't advertise support for removing workspaces, a button
// triggering the remove request should not be displayed.
//
// The compositor will ignore requests it doesn't support. For instance,
// a compositor which doesn't advertise support for remove will ignore
// remove requests.
//
// Compositors must send this event once after creation of an
// ext_workspace_handle_v1 . When the capabilities change, compositors
// must send this event again.
type ExtWorkspaceHandleV1CapabilitiesEvent struct {
	Capabilities uint32
}
type ExtWorkspaceHandleV1CapabilitiesHandlerFunc func(ExtWorkspaceHandleV1CapabilitiesEvent)

// SetCapabilitiesHandler : sets handler for ExtWorkspaceHandleV1CapabilitiesEvent
func (i *ExtWorkspaceHandleV1) SetCapabilitiesHandler(f ExtWorkspaceHandleV1CapabilitiesHandlerFunc) {
	i.capabilitiesHandler = f
}

// ExtWorkspaceHandleV1RemovedEvent : this workspace has been removed
//
// This event is send when the workspace associated with the ext_workspace_handle_v1
// has been removed. After sending this request, the compositor will immediately consider
// the object inert. Any requests will be ignored except the destroy request.
//
// It is guaranteed there won't be any more events referencing this
// ext_workspace_handle_v1.
//
// The compositor must only remove a workspaces not currently belonging to any
// workspace_group.
type ExtWorkspaceHandleV1RemovedEvent struct{}
type ExtWorkspaceHandleV1RemovedHandlerFunc func(ExtWorkspaceHandleV1RemovedEvent)

// SetRemovedHandler : sets handler for ExtWorkspaceHandleV1RemovedEvent
func (i *ExtWorkspaceHandleV1) SetRemovedHandler(f ExtWorkspaceHandleV1RemovedHandlerFunc) {
	i.removedHandler = f
}

func (i *ExtWorkspaceHandleV1) Dispatch(opcode uint32, fd int, data []byte) {
	switch opcode {
	case 0:
		if i.idHandler == nil {
			return
		}
		var e ExtWorkspaceHandleV1IdEvent
		l := 0
		idLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
		l += 4
		e.Id = client.String(data[l : l+idLen])
		l += idLen

		i.idHandler(e)
	case 1:
		if i.nameHandler == nil {
			return
		}
		var e ExtWorkspaceHandleV1NameEvent
		l := 0
		nameLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
		l += 4
		e.Name = client.String(data[l : l+nameLen])
		l += nameLen

		i.nameHandler(e)
	case 2:
		if i.coordinatesHandler == nil {
			return
		}
		var e ExtWorkspaceHandleV1CoordinatesEvent
		l := 0
		coordinatesLen := int(client.Uint32(data[l : l+4]))
		l += 4
		e.Coordinates = make([]byte, coordinatesLen)
		copy(e.Coordinates, data[l:l+coordinatesLen])
		l += coordinatesLen

		i.coordinatesHandler(e)
	case 3:
		if i.stateHandler == nil {
			return
		}
		var e ExtWorkspaceHandleV1StateEvent
		l := 0
		e.State = client.Uint32(data[l : l+4])
		l += 4

		i.stateHandler(e)
	case 4:
		if i.capabilitiesHandler == nil {
			return
		}
		var e ExtWorkspaceHandleV1CapabilitiesEvent
		l := 0
		e.Capabilities = client.Uint32(data[l : l+4])
		l += 4

		i.capabilitiesHandler(e)
	case 5:
		if i.removedHandler == nil {
			return
		}
		var e ExtWorkspaceHandleV1RemovedEvent

		i.removedHandler(e)
	}
}
