The actual initial commit.
parent
e0df2fcb23
commit
870fcf2620
|
|
@ -0,0 +1,4 @@
|
|||
.projectile
|
||||
bar
|
||||
run
|
||||
compile_flags.txt
|
||||
12
README.md
12
README.md
|
|
@ -1,2 +1,14 @@
|
|||
# dwl-bar
|
||||
dwm-like bar for dwl
|
||||
|
||||
Still in development. But should compile.
|
||||
|
||||
## Compile
|
||||
Compile with this command `gcc ./src/*.c -o ./bar $(pkg-config --cflags --libs wayland-client wayland-cursor pangocairo)`.
|
||||
|
||||
## Dependencies
|
||||
I'm not sure what the package names will be for your distrobution, so just make sure these are generally what you have.
|
||||
+ pango
|
||||
+ cairo
|
||||
+ wayland
|
||||
+ wayland-protocols
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This is largely ripped from somebar's ipc patchset; just with some personal modifications.
|
||||
I would probably just submit raphi's patchset but I don't think that would be polite.
|
||||
-->
|
||||
<protocol name="dwl_bar_ipc_unstable_v1">
|
||||
<description summary="inter-proccess-communication about dwl's state">
|
||||
This protocol allows clients to get updates from dwl and vice versa.
|
||||
|
||||
Warning! This protocol is experimental and may make backward incompatible changes.
|
||||
</description>
|
||||
|
||||
<interface name="zdwl_manager_v1" version="1">
|
||||
<description summary="manage dwl state">
|
||||
This interface is exposed as a global in wl_registry.
|
||||
|
||||
Clients can use this interface to get a dwl_output.
|
||||
After binding the client will revieve dwl_manager.tag and dwl_manager.layout events.
|
||||
The dwl_manager.tag and dwl_manager.layout events expose tags and layouts to the client.
|
||||
</description>
|
||||
|
||||
<request name="release" type="destructor">
|
||||
<description summary="release dwl_manager">
|
||||
Indicates that the client will not the dwl_manager object anymore.
|
||||
Objects created through this instance are not affected.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_output">
|
||||
<description summary="get a dwl_output for a wl_output">
|
||||
Get a dwl_output for the specified wl_output.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zdwl_output_v1"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
|
||||
<event name="tag">
|
||||
<description summary="Announces a tag">
|
||||
This event is sent after binding.
|
||||
A roundtrip after binding guarantees the client recieved all tags.
|
||||
</description>
|
||||
<arg name="name" type="string"/>
|
||||
</event>
|
||||
|
||||
<event name="layout">
|
||||
<description summary="Announces a layout">
|
||||
This event is sent after binding.
|
||||
A roundtrip after binding guarantees the client recieved all layouts.
|
||||
</description>
|
||||
<arg name="name" type="string"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zdwl_output_v1" version="1">
|
||||
<description summary="control dwl output">
|
||||
Observe and control a dwl output.
|
||||
|
||||
Events are double-buffered:
|
||||
Clients should cache events and redraw when a dwl_output.done event is sent.
|
||||
|
||||
Request are not double-buffered:
|
||||
The compositor will update immediately upon request.
|
||||
</description>
|
||||
|
||||
<enum name="tag_state">
|
||||
<entry name="none" value="0" summary="no state"/>
|
||||
<entry name="active" value="1" summary="tag is active"/>
|
||||
<entry name="urgent" value="2" summary="tag has at least one urgent client"/>
|
||||
</enum>
|
||||
|
||||
<request name="release" type="destructor">
|
||||
<description summary="release dwl_output">
|
||||
Indicates to that the client no longer needs this dwl_output.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="toggle_visibility">
|
||||
<description summary="Toggle client visibilty">
|
||||
Indicates the client should hide or show themselves.
|
||||
If the client is visible then hide, if hidden then show.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="active">
|
||||
<description summary="Update the selected output.">
|
||||
Indicates if the output is active. Zero is invalid, nonzero is valid.
|
||||
</description>
|
||||
<arg name="active" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="tag">
|
||||
<description summary="Update the state of a tag.">
|
||||
Indicates that a tag has been updated.
|
||||
</description>
|
||||
<arg name="tag" type="uint" summary="Index of the tag"/>
|
||||
<arg name="state" type="uint" enum="tag_state" summary="The state of the tag."/>
|
||||
<arg name="clients" type="uint" summary="The number of clients in the tag."/>
|
||||
<arg name="focused" type="uint" summary="If there is a focused client. Nonzero being valid, zero being invalid."/>
|
||||
</event>
|
||||
|
||||
<event name="layout">
|
||||
<description summary="Update the layout.">
|
||||
Indicates a new layout is selected.
|
||||
</description>
|
||||
<arg name="layout" type="uint" summary="Index of the layout."/>
|
||||
</event>
|
||||
|
||||
<event name="title">
|
||||
<description summary="Update the title.">
|
||||
Indicates the title has changed.
|
||||
</description>
|
||||
<arg name="title" type="string" summary="The new title name."/>
|
||||
</event>
|
||||
|
||||
<event name="frame">
|
||||
<description summary="The update sequence is done.">
|
||||
Indicates that a sequence of status updates have finished and the client should redraw.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="set_layout">
|
||||
<description summary="Set the layout of this output"/>
|
||||
<arg name="index" type="uint" summary="index of a layout recieved by dwl_manager.layout"/>
|
||||
</request>
|
||||
|
||||
<request name="set_tags">
|
||||
<description summary="Set the active tags of this output"/>
|
||||
<arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/>
|
||||
<arg name="toggle_tagset" type="uint" summary="toggle the selected tagset, zero for invalid, nonzero for valid."/>
|
||||
</request>
|
||||
|
||||
<request name="set_client_tags">
|
||||
<description summary="Set the tags of the focused client.">
|
||||
The tags are updated as follows:
|
||||
new_tags = (current_tags AND and_tags) XOR xor_tags
|
||||
</description>
|
||||
<arg name="and_tags" type="uint"/>
|
||||
<arg name="xor_tags" type="uint"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_layer_shell_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2017 Drew DeVault
|
||||
|
||||
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="zwlr_layer_shell_v1" version="4">
|
||||
<description summary="create surfaces that are layers of the desktop">
|
||||
Clients can use this interface to assign the surface_layer role to
|
||||
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
rendered with a defined z-depth respective to each other. They may also be
|
||||
anchored to the edges and corners of a screen and specify input handling
|
||||
semantics. This interface should be suitable for the implementation of
|
||||
many desktop shell components, and a broad number of other applications
|
||||
that interact with the desktop.
|
||||
</description>
|
||||
|
||||
<request name="get_layer_surface">
|
||||
<description summary="create a layer_surface from a surface">
|
||||
Create a layer surface for an existing surface. This assigns the role of
|
||||
layer_surface, or raises a protocol error if another role is already
|
||||
assigned.
|
||||
|
||||
Creating a layer surface from a wl_surface which has a buffer attached
|
||||
or committed is a client error, and any attempts by a client to attach
|
||||
or manipulate a buffer prior to the first layer_surface.configure call
|
||||
must also be treated as errors.
|
||||
|
||||
After creating a layer_surface object and setting it up, the client
|
||||
must perform an initial commit without any buffer attached.
|
||||
The compositor will reply with a layer_surface.configure event.
|
||||
The client must acknowledge it and is then allowed to attach a buffer
|
||||
to map the surface.
|
||||
|
||||
You may pass NULL for output to allow the compositor to decide which
|
||||
output to use. Generally this will be the one that the user most
|
||||
recently interacted with.
|
||||
|
||||
Clients can specify a namespace that defines the purpose of the layer
|
||||
surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
|
||||
<arg name="name_space" type="string" summary="namespace for the layer surface"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="role" value="0" summary="wl_surface has another role"/>
|
||||
<entry name="invalid_layer" value="1" summary="layer value is invalid"/>
|
||||
<entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
|
||||
</enum>
|
||||
|
||||
<enum name="layer">
|
||||
<description summary="available layers for surfaces">
|
||||
These values indicate which layers a surface can be rendered in. They
|
||||
are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||
will typically be rendered between the bottom and top layers.
|
||||
Fullscreen shell surfaces are typically rendered at the top layer.
|
||||
Multiple surfaces can share a single layer, and ordering within a
|
||||
single layer is undefined.
|
||||
</description>
|
||||
|
||||
<entry name="background" value="0"/>
|
||||
<entry name="bottom" value="1"/>
|
||||
<entry name="top" value="2"/>
|
||||
<entry name="overlay" value="3"/>
|
||||
</enum>
|
||||
|
||||
<!-- Version 3 additions -->
|
||||
|
||||
<request name="destroy" type="destructor" since="3">
|
||||
<description summary="destroy the layer_shell object">
|
||||
This request indicates that the client will not use the layer_shell
|
||||
object any more. Objects that have been created through this instance
|
||||
are not affected.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_layer_surface_v1" version="4">
|
||||
<description summary="layer metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for surfaces that
|
||||
are designed to be rendered as a layer of a stacked desktop-like
|
||||
environment.
|
||||
|
||||
Layer surface state (layer, size, anchor, exclusive zone,
|
||||
margin, interactivity) is double-buffered, and will be applied at the
|
||||
time wl_surface.commit of the corresponding wl_surface is called.
|
||||
|
||||
Attaching a null buffer to a layer surface unmaps it.
|
||||
|
||||
Unmapping a layer_surface means that the surface cannot be shown by the
|
||||
compositor until it is explicitly mapped again. The layer_surface
|
||||
returns to the state it had right after layer_shell.get_layer_surface.
|
||||
The client can re-map the surface by performing a commit without any
|
||||
buffer attached, waiting for a configure event and handling it as usual.
|
||||
</description>
|
||||
|
||||
<request name="set_size">
|
||||
<description summary="sets the size of the surface">
|
||||
Sets the size of the surface in surface-local coordinates. The
|
||||
compositor will display the surface centered with respect to its
|
||||
anchors.
|
||||
|
||||
If you pass 0 for either value, the compositor will assign it and
|
||||
inform you of the assignment in the configure event. You must set your
|
||||
anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||
protocol error. Both values are 0 by default.
|
||||
|
||||
Size is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="set_anchor">
|
||||
<description summary="configures the anchor point of the surface">
|
||||
Requests that the compositor anchor the surface to the specified edges
|
||||
and corners. If two orthogonal edges are specified (e.g. 'top' and
|
||||
'left'), then the anchor point will be the intersection of the edges
|
||||
(e.g. the top left corner of the output); otherwise the anchor point
|
||||
will be centered on that edge, or in the center if none is specified.
|
||||
|
||||
Anchor is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="anchor" type="uint" enum="anchor"/>
|
||||
</request>
|
||||
|
||||
<request name="set_exclusive_zone">
|
||||
<description summary="configures the exclusive geometry of this surface">
|
||||
Requests that the compositor avoids occluding an area with other
|
||||
surfaces. The compositor's use of this information is
|
||||
implementation-dependent - do not assume that this region will not
|
||||
actually be occluded.
|
||||
|
||||
A positive value is only meaningful if the surface is anchored to one
|
||||
edge or an edge and both perpendicular edges. If the surface is not
|
||||
anchored, anchored to only two perpendicular edges (a corner), anchored
|
||||
to only two parallel edges or anchored to all edges, a positive value
|
||||
will be treated the same as zero.
|
||||
|
||||
A positive zone is the distance from the edge in surface-local
|
||||
coordinates to consider exclusive.
|
||||
|
||||
Surfaces that do not wish to have an exclusive zone may instead specify
|
||||
how they should interact with surfaces that do. If set to zero, the
|
||||
surface indicates that it would like to be moved to avoid occluding
|
||||
surfaces with a positive exclusive zone. If set to -1, the surface
|
||||
indicates that it would not like to be moved to accommodate for other
|
||||
surfaces, and the compositor should extend it all the way to the edges
|
||||
it is anchored to.
|
||||
|
||||
For example, a panel might set its exclusive zone to 10, so that
|
||||
maximized shell surfaces are not shown on top of it. A notification
|
||||
might set its exclusive zone to 0, so that it is moved to avoid
|
||||
occluding the panel, but shell surfaces are shown underneath it. A
|
||||
wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||
they stretch below or over the panel.
|
||||
|
||||
The default value is 0.
|
||||
|
||||
Exclusive zone is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="zone" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_margin">
|
||||
<description summary="sets a margin from the anchor point">
|
||||
Requests that the surface be placed some distance away from the anchor
|
||||
point on the output, in surface-local coordinates. Setting this value
|
||||
for edges you are not anchored to has no effect.
|
||||
|
||||
The exclusive zone includes the margin.
|
||||
|
||||
Margin is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="top" type="int"/>
|
||||
<arg name="right" type="int"/>
|
||||
<arg name="bottom" type="int"/>
|
||||
<arg name="left" type="int"/>
|
||||
</request>
|
||||
|
||||
<enum name="keyboard_interactivity">
|
||||
<description summary="types of keyboard interaction possible for a layer shell surface">
|
||||
Types of keyboard interaction possible for layer shell surfaces. The
|
||||
rationale for this is twofold: (1) some applications are not interested
|
||||
in keyboard events and not allowing them to be focused can improve the
|
||||
desktop experience; (2) some applications will want to take exclusive
|
||||
keyboard focus.
|
||||
</description>
|
||||
|
||||
<entry name="none" value="0">
|
||||
<description summary="no keyboard focus is possible">
|
||||
This value indicates that this surface is not interested in keyboard
|
||||
events and the compositor should never assign it the keyboard focus.
|
||||
|
||||
This is the default value, set for newly created layer shell surfaces.
|
||||
|
||||
This is useful for e.g. desktop widgets that display information or
|
||||
only have interaction with non-keyboard input devices.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="exclusive" value="1">
|
||||
<description summary="request exclusive keyboard focus">
|
||||
Request exclusive keyboard focus if this surface is above the shell surface layer.
|
||||
|
||||
For the top and overlay layers, the seat will always give
|
||||
exclusive keyboard focus to the top-most layer which has keyboard
|
||||
interactivity set to exclusive. If this layer contains multiple
|
||||
surfaces with keyboard interactivity set to exclusive, the compositor
|
||||
determines the one receiving keyboard events in an implementation-
|
||||
defined manner. In this case, no guarantee is made when this surface
|
||||
will receive keyboard focus (if ever).
|
||||
|
||||
For the bottom and background layers, the compositor is allowed to use
|
||||
normal focus semantics.
|
||||
|
||||
This setting is mainly intended for applications that need to ensure
|
||||
they receive all keyboard events, such as a lock screen or a password
|
||||
prompt.
|
||||
</description>
|
||||
</entry>
|
||||
<entry name="on_demand" value="2" since="4">
|
||||
<description summary="request regular keyboard focus semantics">
|
||||
This requests the compositor to allow this surface to be focused and
|
||||
unfocused by the user in an implementation-defined manner. The user
|
||||
should be able to unfocus this surface even regardless of the layer
|
||||
it is on.
|
||||
|
||||
Typically, the compositor will want to use its normal mechanism to
|
||||
manage keyboard focus between layer shell surfaces with this setting
|
||||
and regular toplevels on the desktop layer (e.g. click to focus).
|
||||
Nevertheless, it is possible for a compositor to require a special
|
||||
interaction to focus or unfocus layer shell surfaces (e.g. requiring
|
||||
a click even if focus follows the mouse normally, or providing a
|
||||
keybinding to switch focus between layers).
|
||||
|
||||
This setting is mainly intended for desktop shell components (e.g.
|
||||
panels) that allow keyboard interaction. Using this option can allow
|
||||
implementing a desktop shell that can be fully usable without the
|
||||
mouse.
|
||||
</description>
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<request name="set_keyboard_interactivity">
|
||||
<description summary="requests keyboard events">
|
||||
Set how keyboard events are delivered to this surface. By default,
|
||||
layer shell surfaces do not receive keyboard events; this request can
|
||||
be used to change this.
|
||||
|
||||
This setting is inherited by child surfaces set by the get_popup
|
||||
request.
|
||||
|
||||
Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
you do not want to receive them, set the input region on your surface
|
||||
to an empty region.
|
||||
|
||||
Keyboard interactivity is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="keyboard_interactivity" type="uint" enum="keyboard_interactivity"/>
|
||||
</request>
|
||||
|
||||
<request name="get_popup">
|
||||
<description summary="assign this layer_surface as an xdg_popup parent">
|
||||
This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||
should have been created via xdg_surface::get_popup with the parent set
|
||||
to NULL, and this request must be invoked before committing the popup's
|
||||
initial state.
|
||||
|
||||
See the documentation of xdg_popup for more details about what an
|
||||
xdg_popup is and how it is used.
|
||||
</description>
|
||||
<arg name="popup" type="object" interface="xdg_popup"/>
|
||||
</request>
|
||||
|
||||
<request name="ack_configure">
|
||||
<description summary="ack a configure event">
|
||||
When a configure event is received, if a client commits the
|
||||
surface in response to the configure event, then the client
|
||||
must make an ack_configure request sometime before the commit
|
||||
request, passing along the serial of the configure event.
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it only has to ack the last configure event.
|
||||
|
||||
A client is not required to commit immediately after sending
|
||||
an ack_configure request - it may even ack_configure several times
|
||||
before its next surface commit.
|
||||
|
||||
A client may send multiple ack_configure requests before committing, but
|
||||
only the last request sent before a commit indicates which configure
|
||||
event the client really is responding to.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the layer_surface">
|
||||
This request destroys the layer surface.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
The configure event asks the client to resize its surface.
|
||||
|
||||
Clients should arrange their surface for the new states, and then send
|
||||
an ack_configure request with the serial sent in this configure event at
|
||||
some point before committing the new surface.
|
||||
|
||||
The client is free to dismiss all but the last configure event it
|
||||
received.
|
||||
|
||||
The width and height arguments specify the size of the window in
|
||||
surface-local coordinates.
|
||||
|
||||
The size is a hint, in the sense that the client is free to ignore it if
|
||||
it doesn't resize, pick a smaller size (to satisfy aspect ratio or
|
||||
resize in steps of NxM pixels). If the client picks a smaller size and
|
||||
is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
|
||||
surface will be centered on this axis.
|
||||
|
||||
If the width or height arguments are zero, it means the client should
|
||||
decide its own window dimension.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="closed">
|
||||
<description summary="surface should be closed">
|
||||
The closed event is sent by the compositor when the surface will no
|
||||
longer be shown. The output may have been destroyed or the user may
|
||||
have asked for it to be removed. Further changes to the surface will be
|
||||
ignored. The client should destroy the resource after receiving this
|
||||
event, and create a new surface if they so choose.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
|
||||
<entry name="invalid_size" value="1" summary="size is invalid"/>
|
||||
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
|
||||
<entry name="invalid_keyboard_interactivity" value="3" summary="keyboard interactivity is invalid"/>
|
||||
</enum>
|
||||
|
||||
<enum name="anchor" bitfield="true">
|
||||
<entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
|
||||
<entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
|
||||
<entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
|
||||
<entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
|
||||
</enum>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
|
||||
<request name="set_layer" since="2">
|
||||
<description summary="change the layer of the surface">
|
||||
Change the layer that the surface is rendered on.
|
||||
|
||||
Layer is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
|
@ -0,0 +1,480 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
|
||||
#include <pango-1.0/pango/pangocairo.h>
|
||||
#include "cairo-deprecated.h"
|
||||
#include "cairo.h"
|
||||
#include "pango/pango-context.h"
|
||||
#include "pango/pango-font.h"
|
||||
#include "pango/pango-layout.h"
|
||||
#include "pango/pango-types.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "bar.h"
|
||||
#include "common.h"
|
||||
#include "shm.h"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
typedef struct Font Font;
|
||||
typedef struct BarComponent BarComponent;
|
||||
|
||||
static void layerSurface(void* data, zwlr_layer_surface_v1*, uint32_t serial, uint32_t width, uint32_t height);
|
||||
static void frame(void* data, wl_callback* callback, uint32_t callback_data);
|
||||
static void bar_render(Bar* bar);
|
||||
static void bar_tags_render(Bar* bar, cairo_t* painter, int* x);
|
||||
static void bar_layout_render(Bar* bar, cairo_t* painter, int* x);
|
||||
static void bar_title_render(Bar* bar, cairo_t* painter, int* x);
|
||||
static void bar_status_render(Bar* bar, cairo_t* painter, int* x);
|
||||
static void bar_set_colorscheme(Bar* bar, const int** scheme);
|
||||
static void set_color(cairo_t* painter, const int rgba[4]);
|
||||
static void bar_color_background(Bar* bar, cairo_t* painter);
|
||||
static void bar_color_foreground(Bar* bar, cairo_t* painter);
|
||||
static Font getFont(void);
|
||||
static void bar_component_render(Bar* bar, BarComponent* component, cairo_t* painter, uint width, int* x);
|
||||
static int bar_component_width(BarComponent* component);
|
||||
static int bar_component_height(BarComponent* component);
|
||||
|
||||
struct Font {
|
||||
PangoFontDescription* description;
|
||||
|
||||
uint height; /* This is also the same as lrpad from dwm. */
|
||||
};
|
||||
|
||||
struct BarComponent {
|
||||
PangoLayout* layout;
|
||||
int x; /* Right bound of box */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint occupied;
|
||||
uint focusedClient; /* If the tag has a focused client */
|
||||
uint state;
|
||||
BarComponent component;
|
||||
} Tag;
|
||||
|
||||
struct Bar {
|
||||
BarComponent layout, title, status;
|
||||
Tag tags[9];
|
||||
|
||||
PangoContext* context;
|
||||
Font font;
|
||||
|
||||
/* Colors */
|
||||
int background[4], foreground[4];
|
||||
|
||||
uint invalid; /* So we don't redraw twice. */
|
||||
uint active; /* If this bar is on the active monitor */
|
||||
uint floating; /* If the focused client is floating */
|
||||
|
||||
wl_surface* surface;
|
||||
zwlr_layer_surface_v1* layer_surface;
|
||||
|
||||
Shm* shm;
|
||||
};
|
||||
|
||||
// So that the compositor can tell us when it's a good time to render again.
|
||||
const wl_callback_listener frameListener = {
|
||||
.done = frame
|
||||
};
|
||||
|
||||
// So that wlroots can tell us we need to resize.
|
||||
// We really only need to worry about this when the bar is visible (sometimes it isn't).
|
||||
const zwlr_layer_surface_v1_listener layerSurfaceListener = {
|
||||
.configure = layerSurface
|
||||
};
|
||||
|
||||
void layerSurface(void* data, zwlr_layer_surface_v1* _, uint32_t serial, uint32_t width, uint32_t height) {
|
||||
Bar* bar = data;
|
||||
zwlr_layer_surface_v1_ack_configure(bar->layer_surface, serial);
|
||||
|
||||
if (bar->shm) {
|
||||
if (bar->shm->width == width && bar->shm->height) {
|
||||
return;
|
||||
}
|
||||
shm_destroy(bar->shm);
|
||||
}
|
||||
|
||||
bar->shm = shm_create(width, height, WL_SHM_FORMAT_XRGB8888);
|
||||
bar_render(bar);
|
||||
}
|
||||
|
||||
void frame(void* data, wl_callback* callback, uint32_t callback_data) {
|
||||
Bar* bar = data;
|
||||
bar_render(bar);
|
||||
wl_callback_destroy(callback);
|
||||
}
|
||||
|
||||
Font getFont(void) {
|
||||
PangoFontMap* map = pango_cairo_font_map_get_default();
|
||||
if (!map)
|
||||
die("font map");
|
||||
|
||||
PangoFontDescription* desc = pango_font_description_from_string(font);
|
||||
if (!desc)
|
||||
die("font description");
|
||||
|
||||
PangoContext* context = pango_font_map_create_context(map);
|
||||
if (!context)
|
||||
die("temp context");
|
||||
|
||||
PangoFont* fnt = pango_font_map_load_font(map, context, desc);
|
||||
if (!fnt)
|
||||
die("font load");
|
||||
|
||||
PangoFontMetrics* metrics = pango_font_get_metrics(fnt, pango_language_get_default());
|
||||
if (!metrics)
|
||||
die("font metrics");
|
||||
|
||||
Font in = {desc, PANGO_PIXELS(pango_font_metrics_get_height(metrics))};
|
||||
|
||||
pango_font_metrics_unref(metrics);
|
||||
g_object_unref(fnt);
|
||||
g_object_unref(context);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
int bar_component_width(BarComponent* component) {
|
||||
int w;
|
||||
pango_layout_get_size(component->layout, &w, NULL);
|
||||
return PANGO_PIXELS(w);
|
||||
}
|
||||
|
||||
int bar_component_height(BarComponent* component) {
|
||||
int h;
|
||||
pango_layout_get_size(component->layout, NULL, &h);
|
||||
return PANGO_PIXELS(h);
|
||||
}
|
||||
|
||||
void bar_set_colorscheme(Bar* bar, const int** scheme) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
bar->foreground[i] = scheme[0][i];
|
||||
bar->background[i] = scheme[1][i];
|
||||
}
|
||||
}
|
||||
|
||||
void set_color(cairo_t* painter, const int rgba[4]) {
|
||||
cairo_set_source_rgba(painter, rgba[0]/255.0, rgba[1]/255.0, rgba[2]/255.0, rgba[3]/255.0);
|
||||
}
|
||||
|
||||
void bar_color_background(Bar* bar, cairo_t* painter) {
|
||||
set_color(painter, bar->background);
|
||||
}
|
||||
|
||||
void bar_color_foreground(Bar* bar, cairo_t* painter) {
|
||||
set_color(painter, bar->foreground);
|
||||
}
|
||||
|
||||
void bar_component_render(Bar* bar, BarComponent* component, cairo_t* painter, uint width, int* x) {
|
||||
pango_cairo_update_layout(painter, component->layout);
|
||||
component->x = *x+width;
|
||||
|
||||
bar_color_background(bar, painter);
|
||||
cairo_rectangle(painter, *x, 0, width, bar->shm->height);
|
||||
cairo_fill(painter);
|
||||
|
||||
bar_color_foreground(bar, painter);
|
||||
cairo_move_to(painter, *x+(bar->font.height/2.0), 1);
|
||||
pango_cairo_show_layout(painter, component->layout);
|
||||
}
|
||||
|
||||
void bar_tags_render(Bar* bar, cairo_t* painter, int* x) {
|
||||
for ( int i = 0; i < LENGTH(tags); i++ ) {
|
||||
Tag tag = bar->tags[i];
|
||||
uint tagWidth = bar_component_width(&tag.component) + bar->font.height;
|
||||
|
||||
/* Creating the tag */
|
||||
if (tag.state & TAG_ACTIVE) {
|
||||
bar_set_colorscheme(bar, schemes[Active_Scheme]);
|
||||
} else if (tag.state & TAG_URGENT) {
|
||||
bar_set_colorscheme(bar, schemes[Urgent_Scheme]);
|
||||
} else {
|
||||
bar_set_colorscheme(bar, schemes[InActive_Scheme]);
|
||||
}
|
||||
|
||||
bar_component_render(bar, &tag.component, painter, tagWidth, x);
|
||||
|
||||
if (!tag.occupied)
|
||||
goto done;
|
||||
|
||||
/* Creating the occupied tag box */
|
||||
int boxHeight = bar->font.height / 9;
|
||||
int boxWidth = bar->font.height / 6 + 1;
|
||||
|
||||
if (tag.focusedClient) {
|
||||
cairo_rectangle(painter, *x + boxHeight, boxHeight, boxWidth, boxWidth);
|
||||
cairo_fill(painter);
|
||||
} else {
|
||||
cairo_rectangle(painter, *x + boxHeight + 0.5, boxHeight + 0.5, boxWidth, boxWidth);
|
||||
cairo_set_line_width(painter, 1);
|
||||
cairo_stroke(painter);
|
||||
}
|
||||
|
||||
done:
|
||||
*x += tagWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void bar_layout_render(Bar* bar, cairo_t* painter, int* x) {
|
||||
if (!bar)
|
||||
return;
|
||||
|
||||
uint layoutWidth = bar_component_width(&bar->layout) + bar->font.height;
|
||||
|
||||
bar_set_colorscheme(bar, schemes[InActive_Scheme]);
|
||||
bar_component_render(bar, &bar->layout, painter, layoutWidth, x);
|
||||
|
||||
*x += layoutWidth;
|
||||
}
|
||||
|
||||
void bar_title_render(Bar* bar, cairo_t* painter, int* x) {
|
||||
if (!bar)
|
||||
return;
|
||||
|
||||
// HUH For some reason ww - x - (status width) works, but ww - x - status width doesn't?
|
||||
uint titleWidth = bar->shm->width - *x - (bar_component_width(&bar->status) + bar->font.height);
|
||||
|
||||
bar->active ? bar_set_colorscheme(bar, schemes[Active_Scheme]) : bar_set_colorscheme(bar, schemes[InActive_Scheme]);
|
||||
|
||||
bar_component_render(bar, &bar->title, painter, titleWidth, x);
|
||||
|
||||
if (!bar->floating)
|
||||
goto done;
|
||||
|
||||
int boxHeight = bar->font.height / 9;
|
||||
int boxWidth = bar->font.height / 6 + 1;
|
||||
|
||||
set_color(painter, grey3);
|
||||
cairo_rectangle(painter, *x + boxHeight + 0.5, boxHeight + 0.5, boxWidth, boxWidth);
|
||||
cairo_set_line_width(painter, 1);
|
||||
cairo_stroke(painter);
|
||||
|
||||
done:
|
||||
*x += titleWidth;
|
||||
}
|
||||
|
||||
void bar_status_render(Bar* bar, cairo_t* painter, int* x) {
|
||||
if (!bar)
|
||||
return;
|
||||
|
||||
uint statusWidth = bar_component_width(&bar->status) + bar->font.height;
|
||||
|
||||
bar_set_colorscheme(bar, schemes[InActive_Scheme]);
|
||||
if (!bar->active && status_on_active)
|
||||
bar_set_colorscheme(bar, (const int*[4]){ grey1, grey1 } );
|
||||
|
||||
bar_component_render(bar, &bar->status, painter, statusWidth, x);
|
||||
}
|
||||
|
||||
void bar_render(Bar* bar) {
|
||||
if (!bar || !bar->shm)
|
||||
return;
|
||||
|
||||
int x = 0; /* Keep track of the cairo cursor */
|
||||
cairo_surface_t* image = cairo_image_surface_create_for_data(shm_data(bar->shm),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
bar->shm->width,
|
||||
bar->shm->height,
|
||||
bar->shm->stride);
|
||||
|
||||
cairo_t* painter = cairo_create(image);
|
||||
pango_cairo_update_context(painter, bar->context);
|
||||
|
||||
bar_tags_render(bar, painter, &x);
|
||||
bar_layout_render(bar, painter, &x);
|
||||
bar_title_render(bar, painter, &x);
|
||||
bar_status_render(bar, painter, &x);
|
||||
|
||||
wl_surface_attach(bar->surface, shm_buffer(bar->shm), 0, 0);
|
||||
wl_surface_damage(bar->surface, 0, 0, bar->shm->width, bar->shm->height);
|
||||
wl_surface_commit(bar->surface);
|
||||
|
||||
cairo_destroy(painter);
|
||||
cairo_surface_destroy(image);
|
||||
|
||||
shm_flip(bar->shm);
|
||||
bar->invalid = 0;
|
||||
}
|
||||
|
||||
Bar* bar_create(void) {
|
||||
Bar* bar = ecalloc(1, sizeof(*bar));
|
||||
bar->invalid = 0;
|
||||
bar->active = 0;
|
||||
bar->floating = 0;
|
||||
|
||||
bar->context = pango_font_map_create_context(pango_cairo_font_map_get_default());
|
||||
if (!bar->context)
|
||||
die("pango context");
|
||||
|
||||
bar->font = getFont();
|
||||
bar->layout.layout = pango_layout_new(bar->context);
|
||||
bar->title.layout = pango_layout_new(bar->context);
|
||||
bar->status.layout = pango_layout_new(bar->context);
|
||||
|
||||
bar->layout.x = 0;
|
||||
bar->title.x = 0;
|
||||
bar->status.x = 0;
|
||||
|
||||
pango_layout_set_font_description(bar->layout.layout, bar->font.description);
|
||||
pango_layout_set_font_description(bar->title.layout, bar->font.description);
|
||||
pango_layout_set_font_description(bar->status.layout, bar->font.description);
|
||||
|
||||
char* status = ecalloc(8, sizeof(*status));
|
||||
snprintf(status, 8, "dwl %.1f", VERSION);
|
||||
|
||||
pango_layout_set_text(bar->layout.layout, "[]=", -1);
|
||||
pango_layout_set_text(bar->status.layout, status, -1);
|
||||
|
||||
for ( int i = 0; i < LENGTH(tags); i++ ) { // Initalize the tags
|
||||
PangoLayout* layout = pango_layout_new(bar->context);
|
||||
pango_layout_set_text(layout, tags[i], strlen(tags[i]));
|
||||
pango_layout_set_font_description(layout, bar->font.description);
|
||||
Tag tag = { 0, 0, 0, layout };
|
||||
bar->tags[i] = tag;
|
||||
}
|
||||
|
||||
return bar;
|
||||
}
|
||||
|
||||
void bar_destroy(Bar* bar) {
|
||||
uint i;
|
||||
if ( !bar )
|
||||
return;
|
||||
|
||||
if ( bar->shm )
|
||||
shm_destroy(bar->shm);
|
||||
|
||||
if ( bar->surface )
|
||||
wl_surface_destroy(bar->surface);
|
||||
|
||||
if ( bar->layer_surface )
|
||||
zwlr_layer_surface_v1_destroy(bar->layer_surface);
|
||||
|
||||
if ( bar->context )
|
||||
g_object_unref(bar->context);
|
||||
|
||||
if ( bar->layout.layout )
|
||||
g_object_unref(bar->layout.layout);
|
||||
|
||||
if ( bar->status.layout )
|
||||
g_object_unref(bar->status.layout);
|
||||
|
||||
if ( bar->title.layout )
|
||||
g_object_unref(bar->title.layout);
|
||||
|
||||
for ( i = 0; i < LENGTH(tags); i++) {
|
||||
Tag tag = bar->tags[i];
|
||||
if (tag.component.layout)
|
||||
g_object_unref(tag.component.layout);
|
||||
}
|
||||
|
||||
return free(bar);
|
||||
}
|
||||
|
||||
// When we need to redraw the bar, because of new information or changes.
|
||||
// We don't just redraw the bar immediately, we will wait for the compositor to say it's ready.
|
||||
// This is only for if the bar is shown
|
||||
void bar_invalidate(Bar* bar) {
|
||||
if ( !bar || bar->invalid || !bar_is_visible(bar))
|
||||
return;
|
||||
|
||||
wl_callback* cb = wl_surface_frame(bar->surface);
|
||||
|
||||
wl_callback_add_listener(cb, &frameListener, bar);
|
||||
wl_surface_commit(bar->surface);
|
||||
bar->invalid = 1;
|
||||
}
|
||||
|
||||
void bar_show(Bar* bar, wl_output* output) {
|
||||
if (!bar || !output || bar_is_visible(bar)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bar->surface = wl_compositor_create_surface(compositor);
|
||||
bar->layer_surface = zwlr_layer_shell_v1_get_layer_surface(shell, bar->surface, output, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "doom.dwl-bar");
|
||||
zwlr_layer_surface_v1_add_listener(bar->layer_surface, &layerSurfaceListener, bar);
|
||||
|
||||
int anchor = bar_top ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP : ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||
zwlr_layer_surface_v1_set_anchor(bar->layer_surface,
|
||||
anchor | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
|
||||
|
||||
int height = bar->font.height + 2;
|
||||
zwlr_layer_surface_v1_set_size(bar->layer_surface, 0, height);
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(bar->layer_surface, height);
|
||||
wl_surface_commit(bar->surface);
|
||||
|
||||
}
|
||||
|
||||
int bar_is_visible(Bar* bar) {
|
||||
// This is dumb, but I don't know how else to do this.
|
||||
// We do a negation to convert to boolean int.
|
||||
// Then another negation to get the right boolean output.
|
||||
// That is 1 when there is a surface, 0 when there isn't.
|
||||
return !(!bar->surface);
|
||||
}
|
||||
|
||||
void bar_set_layout(Bar *bar, const char* text) {
|
||||
pango_layout_set_text(bar->layout.layout, text, strlen(text));
|
||||
}
|
||||
|
||||
void bar_set_title(Bar *bar, const char* text) {
|
||||
pango_layout_set_text(bar->title.layout, text, strlen(text));
|
||||
}
|
||||
|
||||
void bar_set_status(Bar *bar, const char* text) {
|
||||
pango_layout_set_text(bar->status.layout, text, strlen(text));
|
||||
}
|
||||
|
||||
void bar_set_active(Bar* bar, uint is_active) {
|
||||
bar->active = is_active;
|
||||
}
|
||||
|
||||
void bar_set_floating(Bar* bar, uint is_floating) {
|
||||
bar->floating = is_floating;
|
||||
}
|
||||
|
||||
void bar_set_tag(Bar *bar, uint i, uint state, uint occupied, uint focusedClient) {
|
||||
Tag* tag = &bar->tags[i];
|
||||
tag->focusedClient = focusedClient;
|
||||
tag->occupied = occupied;
|
||||
tag->state = state;
|
||||
}
|
||||
|
||||
wl_surface* bar_get_surface(Bar *bar) {
|
||||
return bar->surface;
|
||||
}
|
||||
|
||||
void bar_click(Bar* bar, struct Monitor* monitor, int x, int y, uint32_t button) {
|
||||
Arg* arg = NULL;
|
||||
Clicked location = Click_None;
|
||||
|
||||
if (x < bar->tags[LENGTH(bar->tags)-1].component.x) {
|
||||
location = Click_Tag;
|
||||
for (int i = 0; i < LENGTH(bar->tags); i++) {
|
||||
if (x < bar->tags[i].component.x) {
|
||||
arg->ui = 1<<i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (x < bar->layout.x) {
|
||||
location = Click_Layout;
|
||||
} else if (x < bar->title.x) {
|
||||
location = Click_Title;
|
||||
} else {
|
||||
location = Click_Status;
|
||||
}
|
||||
|
||||
if (location == Click_None)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < LENGTH(buttons); i++) {
|
||||
if (buttons[i].location == location && buttons[i].button == button) {
|
||||
buttons[i].func(monitor, arg ? arg : &buttons[i].arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef BAR_H_
|
||||
#define BAR_H_
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include "common.h"
|
||||
|
||||
typedef struct Bar Bar;
|
||||
|
||||
enum TagState {
|
||||
None = 0,
|
||||
Active = 1,
|
||||
Urgent = 2,
|
||||
};
|
||||
|
||||
#define TAG_INACTIVE None
|
||||
#define TAG_ACTIVE Active
|
||||
#define TAG_URGENT Urgent
|
||||
|
||||
Bar* bar_create(void);
|
||||
void bar_destroy(Bar* bar);
|
||||
void bar_invalidate(Bar* bar);
|
||||
void bar_show(Bar* bar, wl_output* output);
|
||||
int bar_is_visible(Bar* bar);
|
||||
void bar_click(Bar* bar, struct Monitor* monitor, int x, int y, uint32_t button);
|
||||
void bar_set_status(Bar* bar, const char* text);
|
||||
void bar_set_title(Bar* bar, const char* text);
|
||||
void bar_set_layout(Bar* bar, const char* text);
|
||||
void bar_set_active(Bar* bar, uint is_active);
|
||||
void bar_set_floating(Bar* bar, uint is_floating);
|
||||
void bar_set_tag(Bar* bar, uint tag, uint state, uint occupied, uint focusedClient);
|
||||
wl_surface* bar_get_surface(Bar* bar);
|
||||
|
||||
#endif // BAR_H_
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <wayland-cursor.h>
|
||||
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0] )
|
||||
#define VERSION 1.0
|
||||
|
||||
// Commonly used typedefs which makes using these structs easier.
|
||||
typedef struct wl_registry wl_registry;
|
||||
typedef struct wl_interface wl_interface;
|
||||
typedef struct wl_display wl_display;
|
||||
typedef struct wl_compositor wl_compositor;
|
||||
typedef struct wl_shm wl_shm;
|
||||
typedef struct wl_shm_pool wl_shm_pool;
|
||||
typedef struct wl_buffer wl_buffer;
|
||||
typedef struct wl_list wl_list;
|
||||
typedef struct wl_output wl_output;
|
||||
typedef struct xdg_wm_base xdg_wm_base;
|
||||
typedef struct zwlr_layer_shell_v1 zwlr_layer_shell_v1;
|
||||
typedef struct wl_surface wl_surface;
|
||||
typedef struct zwlr_layer_surface_v1 zwlr_layer_surface_v1;
|
||||
typedef struct wl_callback wl_callback;
|
||||
typedef struct wl_callback_listener wl_callback_listener;
|
||||
typedef struct zwlr_layer_surface_v1_listener zwlr_layer_surface_v1_listener;
|
||||
typedef struct zxdg_output_manager_v1 zxdg_output_manager_v1;
|
||||
typedef struct zxdg_output_v1 zxdg_output_v1;
|
||||
typedef struct wl_seat wl_seat;
|
||||
typedef struct wl_pointer wl_pointer;
|
||||
typedef struct wl_keyboard wl_keyboard;
|
||||
typedef struct wl_array wl_array;
|
||||
typedef struct wl_cursor_theme wl_cursor_theme;
|
||||
typedef struct wl_cursor_image wl_cursor_image;
|
||||
typedef struct pollfd pollfd;
|
||||
typedef enum wl_shm_format wl_shm_format;
|
||||
|
||||
extern wl_display* display;
|
||||
extern wl_compositor* compositor;
|
||||
extern wl_shm* shm;
|
||||
extern zwlr_layer_shell_v1* shell;
|
||||
extern FILE* file;
|
||||
|
||||
struct Monitor;
|
||||
|
||||
typedef enum { Click_None, Click_Tag, Click_Layout, Click_Title, Click_Status } Clicked;
|
||||
typedef enum { InActive_Scheme = 0, Active_Scheme = 1, Urgent_Scheme = 2 } ColorScheme;
|
||||
|
||||
typedef union {
|
||||
uint ui;
|
||||
const void* v;
|
||||
} Arg;
|
||||
|
||||
typedef struct {
|
||||
Clicked location;
|
||||
int button;
|
||||
void (*func)(struct Monitor* monitor, const Arg* arg);
|
||||
Arg arg;
|
||||
} Button;
|
||||
|
||||
/* Commonly used functions for allocation and program killing */
|
||||
void die(const char* fmt, ...);
|
||||
void* ecalloc(size_t amnt, size_t size);
|
||||
|
||||
extern void logln(const char* str);
|
||||
|
||||
extern void _logf(const char* fmt, ...);
|
||||
|
||||
/*
|
||||
* User function definitions.
|
||||
* Usually used for when clicking buttons with a pointer.
|
||||
*/
|
||||
void spawn(struct Monitor* monitor, const Arg* arg);
|
||||
void layout(struct Monitor* monitor, const Arg* arg);
|
||||
void view(struct Monitor* monitor, const Arg* arg);
|
||||
void toggle_view(struct Monitor* monitor, const Arg* arg);
|
||||
void tag(struct Monitor* monitor, const Arg* arg);
|
||||
|
||||
#endif // COMMON_H_
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
#include "common.h"
|
||||
#include <linux/input-event-codes.h>
|
||||
|
||||
static const int bar_top = 1; /* Boolean value, non-zero is true. If not top then bottom */
|
||||
static const int status_on_active = 0; /* Display the status on active monitor only. If not then on all. */
|
||||
static const char* font = "Monospace 10";
|
||||
static const char* terminal[] = { "alacritty", NULL };
|
||||
|
||||
/*
|
||||
* Colors:
|
||||
* Colors are in rgba format.
|
||||
* The color scheming format is the same as dwm.
|
||||
* We use an enum as a index for our scheme types.
|
||||
*
|
||||
* cyan - used in an active background
|
||||
* grey3 - used in active text and urgent background
|
||||
* grey1 - used in an inactive background
|
||||
* grey2 - used in inactive text
|
||||
*/
|
||||
static const int cyan[4] = { 0, 85, 119, 255 };
|
||||
static const int grey1[4] = { 34, 34, 34, 255 };
|
||||
static const int grey2[4] = { 187, 187, 187, 255 };
|
||||
static const int grey3[4] = { 238, 238, 238, 255 };
|
||||
|
||||
static const int* schemes[3][2] = {
|
||||
/* Scheme Type fg, bg */
|
||||
[InActive_Scheme] = {grey2, grey1},
|
||||
[Active_Scheme] = {grey3, cyan},
|
||||
[Urgent_Scheme] = {grey1, grey3},
|
||||
};
|
||||
|
||||
/*
|
||||
* Tags
|
||||
*/
|
||||
static const char* tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
||||
|
||||
/*
|
||||
* Buttons
|
||||
* Structure is:
|
||||
* { click location, button clicked (linux event codes), function to run, other argument input (usage varies) }
|
||||
*/
|
||||
static const Button buttons[] = {
|
||||
//{ Click_Tag, BTN_LEFT, view, {0}},
|
||||
//{ Click_Tag, BTN_MIDDLE, tag, {0}},
|
||||
//{ Click_Tag, BTN_RIGHT, toggle_view, {0}},
|
||||
//{ Click_Layout, BTN_LEFT, layout, {.ui = 0}},
|
||||
//{ Click_Layout, BTN_RIGHT, layout, {.ui = 1}},
|
||||
{ Click_Status, BTN_MIDDLE, spawn, {.v = terminal } },
|
||||
};
|
||||
|
||||
#endif // CONFIG_H_
|
||||
|
|
@ -0,0 +1,417 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
#ifndef DWL_BAR_IPC_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define DWL_BAR_IPC_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_dwl_bar_ipc_unstable_v1 The dwl_bar_ipc_unstable_v1 protocol
|
||||
* inter-proccess-communication about dwl's state
|
||||
*
|
||||
* @section page_desc_dwl_bar_ipc_unstable_v1 Description
|
||||
*
|
||||
* This protocol allows clients to get updates from dwl and vice versa.
|
||||
*
|
||||
* Warning! This protocol is experimental and may make backward incompatible changes.
|
||||
*
|
||||
* @section page_ifaces_dwl_bar_ipc_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zdwl_manager_v1 - manage dwl state
|
||||
* - @subpage page_iface_zdwl_output_v1 - control dwl output
|
||||
*/
|
||||
struct wl_output;
|
||||
struct zdwl_manager_v1;
|
||||
struct zdwl_output_v1;
|
||||
|
||||
#ifndef ZDWL_MANAGER_V1_INTERFACE
|
||||
#define ZDWL_MANAGER_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zdwl_manager_v1 zdwl_manager_v1
|
||||
* @section page_iface_zdwl_manager_v1_desc Description
|
||||
*
|
||||
* This interface is exposed as a global in wl_registry.
|
||||
*
|
||||
* Clients can use this interface to get a dwl_output.
|
||||
* After binding the client will revieve dwl_manager.tag and dwl_manager.layout events.
|
||||
* The dwl_manager.tag and dwl_manager.layout events expose tags and layouts to the client.
|
||||
* @section page_iface_zdwl_manager_v1_api API
|
||||
* See @ref iface_zdwl_manager_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zdwl_manager_v1 The zdwl_manager_v1 interface
|
||||
*
|
||||
* This interface is exposed as a global in wl_registry.
|
||||
*
|
||||
* Clients can use this interface to get a dwl_output.
|
||||
* After binding the client will revieve dwl_manager.tag and dwl_manager.layout events.
|
||||
* The dwl_manager.tag and dwl_manager.layout events expose tags and layouts to the client.
|
||||
*/
|
||||
extern const struct wl_interface zdwl_manager_v1_interface;
|
||||
#endif
|
||||
#ifndef ZDWL_OUTPUT_V1_INTERFACE
|
||||
#define ZDWL_OUTPUT_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zdwl_output_v1 zdwl_output_v1
|
||||
* @section page_iface_zdwl_output_v1_desc Description
|
||||
*
|
||||
* Observe and control a dwl output.
|
||||
*
|
||||
* Events are double-buffered:
|
||||
* Clients should cache events and redraw when a dwl_output.done event is sent.
|
||||
*
|
||||
* Request are not double-buffered:
|
||||
* The compositor will update immediately upon request.
|
||||
* @section page_iface_zdwl_output_v1_api API
|
||||
* See @ref iface_zdwl_output_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zdwl_output_v1 The zdwl_output_v1 interface
|
||||
*
|
||||
* Observe and control a dwl output.
|
||||
*
|
||||
* Events are double-buffered:
|
||||
* Clients should cache events and redraw when a dwl_output.done event is sent.
|
||||
*
|
||||
* Request are not double-buffered:
|
||||
* The compositor will update immediately upon request.
|
||||
*/
|
||||
extern const struct wl_interface zdwl_output_v1_interface;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
* @struct zdwl_manager_v1_listener
|
||||
*/
|
||||
struct zdwl_manager_v1_listener {
|
||||
/**
|
||||
* Announces a tag
|
||||
*
|
||||
* This event is sent after binding. A roundtrip after binding
|
||||
* guarantees the client recieved all tags.
|
||||
*/
|
||||
void (*tag)(void *data,
|
||||
struct zdwl_manager_v1 *zdwl_manager_v1,
|
||||
const char *name);
|
||||
/**
|
||||
* Announces a layout
|
||||
*
|
||||
* This event is sent after binding. A roundtrip after binding
|
||||
* guarantees the client recieved all layouts.
|
||||
*/
|
||||
void (*layout)(void *data,
|
||||
struct zdwl_manager_v1 *zdwl_manager_v1,
|
||||
const char *name);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*/
|
||||
static inline int
|
||||
zdwl_manager_v1_add_listener(struct zdwl_manager_v1 *zdwl_manager_v1,
|
||||
const struct zdwl_manager_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zdwl_manager_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZDWL_MANAGER_V1_RELEASE 0
|
||||
#define ZDWL_MANAGER_V1_GET_OUTPUT 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*/
|
||||
#define ZDWL_MANAGER_V1_TAG_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*/
|
||||
#define ZDWL_MANAGER_V1_LAYOUT_SINCE_VERSION 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*/
|
||||
#define ZDWL_MANAGER_V1_RELEASE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*/
|
||||
#define ZDWL_MANAGER_V1_GET_OUTPUT_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zdwl_manager_v1 */
|
||||
static inline void
|
||||
zdwl_manager_v1_set_user_data(struct zdwl_manager_v1 *zdwl_manager_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zdwl_manager_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zdwl_manager_v1 */
|
||||
static inline void *
|
||||
zdwl_manager_v1_get_user_data(struct zdwl_manager_v1 *zdwl_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zdwl_manager_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zdwl_manager_v1_get_version(struct zdwl_manager_v1 *zdwl_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zdwl_manager_v1);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zdwl_manager_v1 */
|
||||
static inline void
|
||||
zdwl_manager_v1_destroy(struct zdwl_manager_v1 *zdwl_manager_v1)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) zdwl_manager_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*
|
||||
* Indicates that the client will not the dwl_manager object anymore.
|
||||
* Objects created through this instance are not affected.
|
||||
*/
|
||||
static inline void
|
||||
zdwl_manager_v1_release(struct zdwl_manager_v1 *zdwl_manager_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zdwl_manager_v1,
|
||||
ZDWL_MANAGER_V1_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_manager_v1
|
||||
*
|
||||
* Get a dwl_output for the specified wl_output.
|
||||
*/
|
||||
static inline struct zdwl_output_v1 *
|
||||
zdwl_manager_v1_get_output(struct zdwl_manager_v1 *zdwl_manager_v1, struct wl_output *output)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_flags((struct wl_proxy *) zdwl_manager_v1,
|
||||
ZDWL_MANAGER_V1_GET_OUTPUT, &zdwl_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zdwl_manager_v1), 0, NULL, output);
|
||||
|
||||
return (struct zdwl_output_v1 *) id;
|
||||
}
|
||||
|
||||
#ifndef ZDWL_OUTPUT_V1_TAG_STATE_ENUM
|
||||
#define ZDWL_OUTPUT_V1_TAG_STATE_ENUM
|
||||
enum zdwl_output_v1_tag_state {
|
||||
/**
|
||||
* no state
|
||||
*/
|
||||
ZDWL_OUTPUT_V1_TAG_STATE_NONE = 0,
|
||||
/**
|
||||
* tag is active
|
||||
*/
|
||||
ZDWL_OUTPUT_V1_TAG_STATE_ACTIVE = 1,
|
||||
/**
|
||||
* tag has at least one urgent client
|
||||
*/
|
||||
ZDWL_OUTPUT_V1_TAG_STATE_URGENT = 2,
|
||||
};
|
||||
#endif /* ZDWL_OUTPUT_V1_TAG_STATE_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
* @struct zdwl_output_v1_listener
|
||||
*/
|
||||
struct zdwl_output_v1_listener {
|
||||
/**
|
||||
* Toggle client visibilty
|
||||
*
|
||||
* Indicates the client should hide or show themselves. If the
|
||||
* client is visible then hide, if hidden then show.
|
||||
*/
|
||||
void (*toggle_visibility)(void *data,
|
||||
struct zdwl_output_v1 *zdwl_output_v1);
|
||||
/**
|
||||
* Update the selected output.
|
||||
*
|
||||
* Indicates if the output is active. Zero is invalid, nonzero is
|
||||
* valid.
|
||||
*/
|
||||
void (*active)(void *data,
|
||||
struct zdwl_output_v1 *zdwl_output_v1,
|
||||
uint32_t active);
|
||||
/**
|
||||
* Update the state of a tag.
|
||||
*
|
||||
* Indicates that a tag has been updated.
|
||||
* @param tag Index of the tag
|
||||
* @param state The state of the tag.
|
||||
* @param clients The number of clients in the tag.
|
||||
* @param focused If there is a focused client. Nonzero being valid, zero being invalid.
|
||||
*/
|
||||
void (*tag)(void *data,
|
||||
struct zdwl_output_v1 *zdwl_output_v1,
|
||||
uint32_t tag,
|
||||
uint32_t state,
|
||||
uint32_t clients,
|
||||
uint32_t focused);
|
||||
/**
|
||||
* Update the layout.
|
||||
*
|
||||
* Indicates a new layout is selected.
|
||||
* @param layout Index of the layout.
|
||||
*/
|
||||
void (*layout)(void *data,
|
||||
struct zdwl_output_v1 *zdwl_output_v1,
|
||||
uint32_t layout);
|
||||
/**
|
||||
* Update the title.
|
||||
*
|
||||
* Indicates the title has changed.
|
||||
* @param title The new title name.
|
||||
*/
|
||||
void (*title)(void *data,
|
||||
struct zdwl_output_v1 *zdwl_output_v1,
|
||||
const char *title);
|
||||
/**
|
||||
* The update sequence is done.
|
||||
*
|
||||
* Indicates that a sequence of status updates have finished and
|
||||
* the client should redraw.
|
||||
*/
|
||||
void (*frame)(void *data,
|
||||
struct zdwl_output_v1 *zdwl_output_v1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
static inline int
|
||||
zdwl_output_v1_add_listener(struct zdwl_output_v1 *zdwl_output_v1,
|
||||
const struct zdwl_output_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zdwl_output_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZDWL_OUTPUT_V1_RELEASE 0
|
||||
#define ZDWL_OUTPUT_V1_SET_LAYOUT 1
|
||||
#define ZDWL_OUTPUT_V1_SET_TAGS 2
|
||||
#define ZDWL_OUTPUT_V1_SET_CLIENT_TAGS 3
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_TOGGLE_VISIBILITY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_ACTIVE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_TAG_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_LAYOUT_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_TITLE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_FRAME_SINCE_VERSION 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_RELEASE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_SET_LAYOUT_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_SET_TAGS_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
#define ZDWL_OUTPUT_V1_SET_CLIENT_TAGS_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zdwl_output_v1 */
|
||||
static inline void
|
||||
zdwl_output_v1_set_user_data(struct zdwl_output_v1 *zdwl_output_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zdwl_output_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zdwl_output_v1 */
|
||||
static inline void *
|
||||
zdwl_output_v1_get_user_data(struct zdwl_output_v1 *zdwl_output_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zdwl_output_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zdwl_output_v1_get_version(struct zdwl_output_v1 *zdwl_output_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zdwl_output_v1);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zdwl_output_v1 */
|
||||
static inline void
|
||||
zdwl_output_v1_destroy(struct zdwl_output_v1 *zdwl_output_v1)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) zdwl_output_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*
|
||||
* Indicates to that the client no longer needs this dwl_output.
|
||||
*/
|
||||
static inline void
|
||||
zdwl_output_v1_release(struct zdwl_output_v1 *zdwl_output_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zdwl_output_v1,
|
||||
ZDWL_OUTPUT_V1_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_output_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
static inline void
|
||||
zdwl_output_v1_set_layout(struct zdwl_output_v1 *zdwl_output_v1, uint32_t index)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zdwl_output_v1,
|
||||
ZDWL_OUTPUT_V1_SET_LAYOUT, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_output_v1), 0, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*/
|
||||
static inline void
|
||||
zdwl_output_v1_set_tags(struct zdwl_output_v1 *zdwl_output_v1, uint32_t tagmask, uint32_t toggle_tagset)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zdwl_output_v1,
|
||||
ZDWL_OUTPUT_V1_SET_TAGS, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_output_v1), 0, tagmask, toggle_tagset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zdwl_output_v1
|
||||
*
|
||||
* The tags are updated as follows:
|
||||
* new_tags = (current_tags AND and_tags) XOR xor_tags
|
||||
*/
|
||||
static inline void
|
||||
zdwl_output_v1_set_client_tags(struct zdwl_output_v1 *zdwl_output_v1, uint32_t and_tags, uint32_t xor_tags)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zdwl_output_v1,
|
||||
ZDWL_OUTPUT_V1_SET_CLIENT_TAGS, NULL, wl_proxy_get_version((struct wl_proxy *) zdwl_output_v1), 0, and_tags, xor_tags);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface zdwl_output_v1_interface;
|
||||
|
||||
static const struct wl_interface *dwl_bar_ipc_unstable_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&zdwl_output_v1_interface,
|
||||
&wl_output_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message zdwl_manager_v1_requests[] = {
|
||||
{ "release", "", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "get_output", "no", dwl_bar_ipc_unstable_v1_types + 4 },
|
||||
};
|
||||
|
||||
static const struct wl_message zdwl_manager_v1_events[] = {
|
||||
{ "tag", "s", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "layout", "s", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface zdwl_manager_v1_interface = {
|
||||
"zdwl_manager_v1", 1,
|
||||
2, zdwl_manager_v1_requests,
|
||||
2, zdwl_manager_v1_events,
|
||||
};
|
||||
|
||||
static const struct wl_message zdwl_output_v1_requests[] = {
|
||||
{ "release", "", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "set_layout", "u", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "set_tags", "uu", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "set_client_tags", "uu", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message zdwl_output_v1_events[] = {
|
||||
{ "toggle_visibility", "", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "active", "u", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "tag", "uuuu", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "layout", "u", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "title", "s", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
{ "frame", "", dwl_bar_ipc_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface zdwl_output_v1_interface = {
|
||||
"zdwl_output_v1", 1,
|
||||
4, zdwl_output_v1_requests,
|
||||
6, zdwl_output_v1_events,
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,901 @@
|
|||
#include <asm-generic/errno-base.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <wayland-client-core.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-cursor.h>
|
||||
#include <wayland-util.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "bar.h"
|
||||
#include "cairo.h"
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "shm.h"
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
/*
|
||||
* When checking to see if two strings are the same with strcmp,
|
||||
* 0 means they are the same, otherwise they are different.
|
||||
*/
|
||||
#define EQUAL 0
|
||||
#define POLLFDS 4
|
||||
|
||||
// TODO Create Github for dwl-bar then patchset for dwl-bar ipc
|
||||
//
|
||||
// TODO Get the ipc wayland protocol working.
|
||||
// + Include a `hide` / `toggle_visibility` event so that the bar can hide itself when the user asks.
|
||||
// TODO Create dwl-ipc patchset then submit to dwl wiki.
|
||||
|
||||
typedef struct Monitor {
|
||||
char *xdg_name;
|
||||
uint32_t registry_name;
|
||||
|
||||
wl_output *output;
|
||||
Bar *bar;
|
||||
wl_list link;
|
||||
} Monitor;
|
||||
|
||||
typedef struct {
|
||||
wl_pointer* pointer;
|
||||
Monitor* focused_monitor;
|
||||
|
||||
int x, y;
|
||||
|
||||
uint32_t* buttons;
|
||||
uint size;
|
||||
} Pointer;
|
||||
|
||||
typedef struct {
|
||||
uint32_t registry_name;
|
||||
wl_seat* seat;
|
||||
wl_list link;
|
||||
|
||||
Pointer* pointer;
|
||||
} Seat;
|
||||
|
||||
typedef struct {
|
||||
wl_output *output;
|
||||
uint32_t name;
|
||||
wl_list link;
|
||||
} uninitOutput;
|
||||
|
||||
typedef struct {
|
||||
wl_registry *registry;
|
||||
uint32_t name;
|
||||
const char *interface_str;
|
||||
} HandleGlobal;
|
||||
|
||||
static void cleanup(void);
|
||||
static void setup(void);
|
||||
static void run(void);
|
||||
static void globalChecks(void);
|
||||
static void checkGlobal(void *global, const char *name);
|
||||
static void monitorSetup(uint32_t name, wl_output *output);
|
||||
static void set_cloexec(int fd);
|
||||
static void sighandler(int _);
|
||||
static void flush(void);
|
||||
static void setupFifo(void);
|
||||
static char* to_delimiter(char* string, ulong *start_end, char delimiter);
|
||||
static char* get_line(int fd);
|
||||
static void on_status(void);
|
||||
static void on_stdin(void);
|
||||
static void handle_stdin(char* line);
|
||||
static Monitor* monitor_from_name(char* name);
|
||||
static Monitor* monitor_from_surface(wl_surface* surface);
|
||||
static void update_monitor(Monitor* monitor);
|
||||
|
||||
/* Register listener related functions */
|
||||
static void onGlobalAdd(void *data, wl_registry *registry, uint32_t name,
|
||||
const char *interface, uint32_t version);
|
||||
static void onGlobalRemove(void *data, wl_registry *registry, uint32_t name);
|
||||
static int regHandle(void **store, HandleGlobal helper,
|
||||
const wl_interface *interface, int version);
|
||||
|
||||
/* xdg listener members */
|
||||
static void ping(void *data, xdg_wm_base *xdg_wm_base, uint32_t serial);
|
||||
static void name(void *data, zxdg_output_v1 *output, const char *name);
|
||||
|
||||
/* seat listener member */
|
||||
static void capabilites(void* data, wl_seat* wl_seat, uint32_t capabilities);
|
||||
|
||||
/* pointer listener members */
|
||||
static void enter(void* data, wl_pointer* pointer, uint32_t serial, wl_surface* surface, wl_fixed_t x, wl_fixed_t y);
|
||||
static void leave(void* data, wl_pointer* pointer, uint32_t serial, wl_surface* surface);
|
||||
static void motion(void* data, wl_pointer* pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y);
|
||||
static void button(void* data, wl_pointer* pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
|
||||
static void frame(void* data, wl_pointer* pointer);
|
||||
|
||||
/* We don't do anything in these functions */
|
||||
static void axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {}
|
||||
static void axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source) {}
|
||||
static void axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis) {}
|
||||
static void axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete) {}
|
||||
static void seat_name(void* data, wl_seat* seat, const char* name) {}
|
||||
|
||||
/* Globals */
|
||||
wl_display *display;
|
||||
wl_compositor *compositor;
|
||||
wl_shm *shm;
|
||||
zwlr_layer_shell_v1 *shell;
|
||||
static xdg_wm_base *base;
|
||||
static zxdg_output_manager_v1 *output_manager;
|
||||
|
||||
/* Cursor */
|
||||
static wl_cursor_image* cursor_image;
|
||||
static wl_surface* cursor_surface;
|
||||
|
||||
/* Lists */
|
||||
static wl_list seats;
|
||||
static wl_list monitors;
|
||||
static wl_list uninitializedOutputs;
|
||||
|
||||
/* File Descriptors */
|
||||
static pollfd *pollfds;
|
||||
static int wl_display_fd;
|
||||
static int self_pipe[2];
|
||||
static int fifo_fd;
|
||||
static char* fifo_path;
|
||||
|
||||
/* Sigactions */
|
||||
static struct sigaction sighandle;
|
||||
static struct sigaction child_handle;
|
||||
|
||||
FILE* file;
|
||||
|
||||
/*
|
||||
* So that the global handler knows that we can initialize an output.
|
||||
* Rather than just store it for when we have all of our globals.
|
||||
*
|
||||
* Since wayland is asynchronous we may get our outputs before we're ready for
|
||||
* them.
|
||||
*/
|
||||
static int ready = 0;
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = onGlobalAdd,
|
||||
.global_remove = onGlobalRemove,
|
||||
};
|
||||
|
||||
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
|
||||
.ping = ping,
|
||||
};
|
||||
|
||||
/* So that we can get the monitor names to match with dwl monitor names. */
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
.name = name,
|
||||
};
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
.enter = enter,
|
||||
.leave = leave,
|
||||
.motion = motion,
|
||||
.button = button,
|
||||
.frame = frame,
|
||||
|
||||
.axis = axis,
|
||||
.axis_discrete = axis_discrete,
|
||||
.axis_source = axis_source,
|
||||
.axis_stop = axis_stop,
|
||||
};
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
.capabilities = capabilites,
|
||||
.name = seat_name,
|
||||
};
|
||||
|
||||
void enter(void *data, wl_pointer *pointer, uint32_t serial,
|
||||
wl_surface *surface, wl_fixed_t x, wl_fixed_t y) {
|
||||
Seat seat = *(Seat*)data;
|
||||
seat.pointer->focused_monitor = monitor_from_surface(surface);
|
||||
|
||||
if (!cursor_image) {
|
||||
wl_cursor_theme *theme = wl_cursor_theme_load(NULL, 24, shm);
|
||||
cursor_image = wl_cursor_theme_get_cursor(theme, "left_ptr")->images[0];
|
||||
cursor_surface = wl_compositor_create_surface(compositor);
|
||||
wl_surface_attach(cursor_surface, wl_cursor_image_get_buffer(cursor_image), 0, 0);
|
||||
wl_surface_commit(cursor_surface);
|
||||
}
|
||||
|
||||
wl_pointer_set_cursor(pointer, serial, cursor_surface,
|
||||
cursor_image->hotspot_x, cursor_image->hotspot_y);
|
||||
}
|
||||
|
||||
void leave(void* data, wl_pointer* pointer, uint32_t serial, wl_surface* surface) {
|
||||
Seat seat = *(Seat*)data;
|
||||
seat.pointer->focused_monitor = NULL;
|
||||
}
|
||||
|
||||
void motion(void* data, wl_pointer* pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y) {
|
||||
Seat seat = *(Seat*)data;
|
||||
seat.pointer->x = wl_fixed_to_int(x);
|
||||
seat.pointer->y = wl_fixed_to_int(y);
|
||||
}
|
||||
|
||||
void button(void *data, wl_pointer *pointer, uint32_t serial, uint32_t time,
|
||||
uint32_t button, uint32_t state) {
|
||||
Seat seat = *(Seat*)data;
|
||||
int i, prev = -1; /* The index of this button */
|
||||
|
||||
for (i = 0; i < seat.pointer->size; i++) {
|
||||
_logf("'%d' ", seat.pointer->buttons[i]);
|
||||
if (seat.pointer->buttons[i] == button)
|
||||
prev = i;
|
||||
}
|
||||
|
||||
/* If this button was newly pressed. */
|
||||
if (state == WL_POINTER_BUTTON_STATE_PRESSED && prev == -1) {
|
||||
uint32_t* new_buttons = ecalloc(seat.pointer->size+1, sizeof(uint32_t));
|
||||
for (i = 0; i < seat.pointer->size+1; i++) {
|
||||
if (i == seat.pointer->size) {
|
||||
new_buttons[i] = button;
|
||||
break;
|
||||
}
|
||||
|
||||
new_buttons[i] = seat.pointer->buttons[i];
|
||||
}
|
||||
|
||||
free(seat.pointer->buttons);
|
||||
seat.pointer->buttons = new_buttons;
|
||||
seat.pointer->size++;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this button was released and we have it. */
|
||||
if(state == WL_KEYBOARD_KEY_STATE_RELEASED && prev != -1) {
|
||||
uint32_t* new_buttons = ecalloc(seat.pointer->size-1, sizeof(uint32_t));
|
||||
for (i = 0; i < seat.pointer->size; i++) {
|
||||
if (i == prev)
|
||||
continue;
|
||||
|
||||
if (i < prev)
|
||||
new_buttons[i] = seat.pointer->buttons[i];
|
||||
|
||||
if (i > prev)
|
||||
new_buttons[i-1] = seat.pointer->buttons[i];
|
||||
}
|
||||
|
||||
free(seat.pointer->buttons);
|
||||
seat.pointer->buttons = new_buttons;
|
||||
seat.pointer->size--;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void frame(void* data, wl_pointer* pointer) {
|
||||
Seat seat = *(Seat*)data;
|
||||
Monitor* monitor = seat.pointer->focused_monitor;
|
||||
if (!monitor) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < seat.pointer->size; i++) {
|
||||
bar_click(monitor->bar, monitor, seat.pointer->x, seat.pointer->y, seat.pointer->buttons[i]);
|
||||
}
|
||||
|
||||
free(seat.pointer->buttons);
|
||||
seat.pointer->buttons = NULL;
|
||||
seat.pointer->size = 0;
|
||||
}
|
||||
|
||||
void capabilites(void* data, wl_seat* wl_seat, uint32_t capabilities) {
|
||||
Seat* seat = data;
|
||||
int has_pointer = capabilities & WL_SEAT_CAPABILITY_POINTER;
|
||||
if (!seat->pointer && has_pointer) {
|
||||
seat->pointer = ecalloc(1, sizeof(Pointer));
|
||||
seat->pointer->pointer = wl_seat_get_pointer(wl_seat);
|
||||
seat->pointer->buttons = NULL;
|
||||
seat->pointer->size = 0;
|
||||
wl_pointer_add_listener(seat->pointer->pointer, &pointer_listener, seat);
|
||||
return;
|
||||
}
|
||||
|
||||
if (seat->pointer && !has_pointer) {
|
||||
wl_pointer_release(seat->pointer->pointer);
|
||||
seat->pointer->focused_monitor = NULL;
|
||||
if (seat->pointer->buttons) {
|
||||
free(seat->pointer->buttons);
|
||||
}
|
||||
free(seat->pointer);
|
||||
}
|
||||
}
|
||||
|
||||
static void name(void *data, zxdg_output_v1 *xdg_output, const char *name) {
|
||||
Monitor *monitor = data;
|
||||
monitor->xdg_name = strdup(name);
|
||||
zxdg_output_v1_destroy(xdg_output);
|
||||
}
|
||||
|
||||
void ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial) {
|
||||
xdg_wm_base_pong(base, serial);
|
||||
}
|
||||
|
||||
int regHandle(void **store, HandleGlobal helper, const wl_interface *interface,
|
||||
int version) {
|
||||
if (strcmp(helper.interface_str, interface->name) != EQUAL)
|
||||
return 0;
|
||||
|
||||
*store = wl_registry_bind(helper.registry, helper.name, interface, version);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void onGlobalAdd(void *_, wl_registry *registry, uint32_t name,
|
||||
const char *interface, uint32_t version) {
|
||||
|
||||
HandleGlobal helper = {registry, name, interface};
|
||||
if (regHandle((void **)&compositor, helper, &wl_compositor_interface, 4))
|
||||
return;
|
||||
if (regHandle((void **)&shm, helper, &wl_shm_interface, 1))
|
||||
return;
|
||||
if (regHandle((void **)&output_manager, helper, &zxdg_output_manager_v1_interface, 3))
|
||||
return;
|
||||
if (regHandle((void **)&shell, helper, &zwlr_layer_shell_v1_interface, 4))
|
||||
return;
|
||||
if (regHandle((void **)&base, helper, &xdg_wm_base_interface, 2)) {
|
||||
xdg_wm_base_add_listener(base, &xdg_wm_base_listener, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
wl_output *output;
|
||||
if (regHandle((void **)&output, helper, &wl_output_interface, 1)) {
|
||||
if (ready) {
|
||||
monitorSetup(name, output);
|
||||
} else {
|
||||
uninitOutput *uninit = ecalloc(1, sizeof(uninitOutput));
|
||||
uninit->output = output;
|
||||
uninit->name = name;
|
||||
wl_list_insert(&uninitializedOutputs, &uninit->link);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
wl_seat* seat;
|
||||
if (regHandle((void**)&seat, helper, &wl_seat_interface, 7)) {
|
||||
Seat* seat_ = ecalloc(1, sizeof(*seat_));
|
||||
seat_->seat = seat;
|
||||
seat_->registry_name = name;
|
||||
wl_list_insert(&seats, &seat_->link);
|
||||
wl_seat_add_listener(seat, &seat_listener, seat_);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onGlobalRemove(void *_, wl_registry *registry, uint32_t name) {
|
||||
/* Deconstruct a monitor when it disappears */
|
||||
Monitor *current_monitor, *tmp_monitor;
|
||||
wl_list_for_each_safe(current_monitor, tmp_monitor, &monitors, link) {
|
||||
if (current_monitor->registry_name == name) {
|
||||
wl_list_remove(¤t_monitor->link);
|
||||
bar_destroy(current_monitor->bar);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deconstruct seat when it disappears */
|
||||
Seat *seat, *tmp_seat;
|
||||
wl_list_for_each_safe(seat, tmp_seat, &seats, link) {
|
||||
if (seat->registry_name == name) {
|
||||
seat->pointer->focused_monitor = NULL;
|
||||
wl_pointer_release(seat->pointer->pointer);
|
||||
wl_list_remove(&seat->link);
|
||||
free(seat->pointer->buttons);
|
||||
free(seat->pointer);
|
||||
free(seat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void spawn(Monitor* monitor, const Arg *arg) {
|
||||
if (fork() != 0)
|
||||
return;
|
||||
|
||||
char* const* argv = arg->v;
|
||||
setsid();
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, "bar: execvp %s", argv[0]);
|
||||
perror(" failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void checkGlobal(void *global, const char *name) {
|
||||
if (global)
|
||||
return;
|
||||
fprintf(stderr, "Wayland server did not export %s\n", name);
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We just check and make sure we have our needed globals if any fail then we
|
||||
* exit.
|
||||
*/
|
||||
void globalChecks() {
|
||||
checkGlobal(compositor, "wl_compositor");
|
||||
checkGlobal(shm, "wl_shm");
|
||||
checkGlobal(base, "xdg_wm_base");
|
||||
checkGlobal(shell, "wlr_layer_shell");
|
||||
checkGlobal(output_manager, "zxdg_output_manager");
|
||||
|
||||
ready = 1;
|
||||
}
|
||||
|
||||
void monitorSetup(uint32_t name, wl_output *output) {
|
||||
Monitor *monitor = ecalloc(1, sizeof(*monitor));
|
||||
|
||||
monitor->bar = bar_create();
|
||||
monitor->output = output;
|
||||
monitor->registry_name = name;
|
||||
|
||||
wl_list_insert(&monitors, &monitor->link);
|
||||
|
||||
// So we can get the monitor name.
|
||||
zxdg_output_v1 *xdg_output = zxdg_output_manager_v1_get_xdg_output(output_manager, output);
|
||||
zxdg_output_v1_add_listener(xdg_output, &xdg_output_listener, monitor);
|
||||
}
|
||||
|
||||
void set_cloexec(int fd) {
|
||||
int flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1)
|
||||
die("FD_GETFD");
|
||||
if (fcntl(fd, flags | FD_CLOEXEC) < 0)
|
||||
die("FDD_SETFD");
|
||||
}
|
||||
|
||||
void sighandler(int _) {
|
||||
if (write(self_pipe[1], "0", 1) < 0)
|
||||
die("sighandler");
|
||||
}
|
||||
|
||||
void flush(void) {
|
||||
wl_display_dispatch_pending(display);
|
||||
if (wl_display_flush(display) < 0 && errno == EAGAIN) {
|
||||
for (int i = 0; i < POLLFDS; i++) {
|
||||
struct pollfd *poll = &pollfds[i];
|
||||
if (poll->fd == wl_display_fd)
|
||||
poll->events |= POLLOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupFifo(void) {
|
||||
int result, fd, i;
|
||||
char *runtime_path = getenv("XDG_RUNTIME_DIR"), *file_name, *path;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
file_name = ecalloc(12, sizeof(*file_name));
|
||||
sprintf(file_name, "/dwl-bar-%d", i);
|
||||
|
||||
path = ecalloc(strlen(runtime_path)+strlen(file_name)+1, sizeof(char));
|
||||
strcat(path, runtime_path);
|
||||
strcat(path, file_name);
|
||||
free(file_name);
|
||||
|
||||
result = mkfifo(path, 0666);
|
||||
if (result < 0) {
|
||||
if (errno != EEXIST)
|
||||
die("mkfifo");
|
||||
|
||||
free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((fd = open(path, O_CLOEXEC | O_RDONLY | O_NONBLOCK)) < 0)
|
||||
die("open fifo");
|
||||
|
||||
fifo_path = path;
|
||||
fifo_fd = fd;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
die("setup fifo"); /* If we get here then we couldn't setup the fifo */
|
||||
}
|
||||
|
||||
void update_monitor(Monitor* monitor) {
|
||||
if (!bar_is_visible(monitor->bar)) {
|
||||
bar_show(monitor->bar, monitor->output);
|
||||
return;
|
||||
}
|
||||
|
||||
bar_invalidate(monitor->bar);
|
||||
return;
|
||||
}
|
||||
|
||||
Monitor* monitor_from_name(char* name) {
|
||||
Monitor* monitor;
|
||||
wl_list_for_each(monitor, &monitors, link) {
|
||||
if (strcmp(name, monitor->xdg_name) == EQUAL)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Monitor* monitor_from_surface(wl_surface* surface) {
|
||||
Monitor* monitor;
|
||||
wl_list_for_each(monitor, &monitors, link) {
|
||||
if (surface == bar_get_surface(monitor->bar))
|
||||
return monitor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse and extract a substring based on a delimiter
|
||||
* start_end is a pointer to a ulong that we will use to base our starting location.
|
||||
* Then fill in after as the ending point. To be used later on.
|
||||
*/
|
||||
char* to_delimiter(char* string, ulong *start_end, char delimiter) {
|
||||
char* output;
|
||||
ulong i, len = strlen(string);
|
||||
|
||||
if (*start_end > len)
|
||||
return NULL;
|
||||
|
||||
for ( i = *start_end; i < len; i++ ) {
|
||||
if (string[i] == delimiter || i == len-1) { // We've reached the delimiter or the end.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create and copy the substring what we need */
|
||||
output = strncpy(ecalloc(i - *start_end, sizeof(*output)),
|
||||
string + *start_end, i - *start_end);
|
||||
|
||||
output[i - *start_end] = '\0'; // null terminate
|
||||
*start_end = i+1;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/* The `getline` from stdio.h wasn't working so I've made my own. */
|
||||
char* get_line(int fd) {
|
||||
char *output, buffer[512], character;
|
||||
int i = 0, r = i;
|
||||
|
||||
while ((r = read(fd, &character, 1)) > 0 && i < 512) {
|
||||
buffer[i] = character;
|
||||
i++;
|
||||
|
||||
if (character == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
/* Checking for edge cases */
|
||||
if ((r == 0 && i == 0) || (i == 1 && buffer[i] == '\n'))
|
||||
return NULL;
|
||||
|
||||
buffer[i] = '\0';
|
||||
output = strcpy(ecalloc(i, sizeof(*output)), buffer);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void on_stdin(void) {
|
||||
while (1) {
|
||||
char *buffer = get_line(STDIN_FILENO);
|
||||
if (!buffer || !strlen(buffer)) {
|
||||
free(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
handle_stdin(buffer);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_stdin(char* line) {
|
||||
char *name, *command;
|
||||
Monitor* monitor;
|
||||
ulong loc = 0; /* Keep track of where we are in the string `line` */
|
||||
|
||||
name = to_delimiter(line, &loc, ' ');
|
||||
command = to_delimiter(line, &loc, ' ');
|
||||
monitor = monitor_from_name(name);
|
||||
if (!monitor)
|
||||
return;
|
||||
free(name);
|
||||
|
||||
// Hate the way these if statements look. Is being this explicit worth it?
|
||||
if (strcmp(command, "title") == EQUAL) {
|
||||
if (line[strlen(line)-2] == ' ') {
|
||||
bar_set_title(monitor->bar, "");
|
||||
goto done;
|
||||
}
|
||||
|
||||
char* title = to_delimiter(line, &loc, '\n');
|
||||
bar_set_title(monitor->bar, title);
|
||||
free(title);
|
||||
|
||||
} else if (strcmp(command, "floating") == EQUAL) {
|
||||
if (line[strlen(line)-2] == ' ') {
|
||||
bar_set_floating(monitor->bar, 0);
|
||||
goto done;
|
||||
}
|
||||
|
||||
char* is_floating = to_delimiter(line, &loc, '\n');
|
||||
strcmp(is_floating, "1") == EQUAL ? bar_set_floating(monitor->bar, 1) : bar_set_floating(monitor->bar, 0);
|
||||
free(is_floating);
|
||||
|
||||
} else if (strcmp(command, "fullscreen") == EQUAL) {
|
||||
/* Do nothing */
|
||||
} else if (strcmp(command, "selmon") == EQUAL) {
|
||||
char* selmon = to_delimiter(line, &loc, '\n');
|
||||
strcmp(selmon, "1") == EQUAL ? bar_set_active(monitor->bar, 1) : bar_set_active(monitor->bar, 0);
|
||||
free(selmon);
|
||||
|
||||
} else if (strcmp(command, "tags") == EQUAL) {
|
||||
char *occupied_, *tags__, *clients_, *urgent_;
|
||||
int occupied, tags_, clients, urgent, i, tag_mask;
|
||||
|
||||
occupied_ = to_delimiter(line, &loc, ' ');
|
||||
tags__ = to_delimiter(line, &loc, ' ');
|
||||
clients_ = to_delimiter(line, &loc, ' ');
|
||||
urgent_ = to_delimiter(line, &loc, '\n');
|
||||
|
||||
occupied = atoi(occupied_);
|
||||
tags_ = atoi(tags__);
|
||||
clients = atoi(clients_);
|
||||
urgent = atoi(urgent_);
|
||||
|
||||
for(i = 0; i < LENGTH(tags); i++) {
|
||||
int state = TAG_INACTIVE;
|
||||
tag_mask = 1 << i;
|
||||
|
||||
if (tags_ & tag_mask)
|
||||
state |= TAG_ACTIVE;
|
||||
if (urgent & tag_mask)
|
||||
state |= TAG_URGENT;
|
||||
|
||||
bar_set_tag(monitor->bar, i, state, occupied & tag_mask ? 1: 0, clients & tag_mask ? 1 : 0);
|
||||
}
|
||||
|
||||
free(occupied_);
|
||||
free(tags__);
|
||||
free(clients_);
|
||||
free(urgent_);
|
||||
|
||||
} else if (strcmp(command, "layout") == EQUAL) {
|
||||
char* layout = to_delimiter(line, &loc, '\n');
|
||||
bar_set_layout(monitor->bar, layout);
|
||||
free(layout);
|
||||
} else {
|
||||
die("command unrecognized");
|
||||
}
|
||||
|
||||
done:
|
||||
free(command);
|
||||
update_monitor(monitor);
|
||||
}
|
||||
|
||||
void on_status(void) {
|
||||
while (1) {
|
||||
char *line = get_line(fifo_fd), *command, *status;
|
||||
ulong loc = 0;
|
||||
if (!line || !strlen(line)) {
|
||||
free(line);
|
||||
return;
|
||||
}
|
||||
|
||||
command = to_delimiter(line, &loc, ' ');
|
||||
status = to_delimiter(line, &loc, '\n');
|
||||
|
||||
if (strcmp(command, "status") != EQUAL) {
|
||||
free(status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
fprintf(file, "'%s'", status);
|
||||
fflush(file);
|
||||
|
||||
Monitor *current_monitor;
|
||||
wl_list_for_each(current_monitor, &monitors, link) {
|
||||
bar_set_status(current_monitor->bar, status);
|
||||
update_monitor(current_monitor);
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
free(line);
|
||||
free(command);
|
||||
free(status);
|
||||
}
|
||||
}
|
||||
|
||||
void setup(void) {
|
||||
file = fopen("log.txt", "w");
|
||||
if (!file)
|
||||
die("file");
|
||||
|
||||
if (pipe(self_pipe) < 0)
|
||||
die("pipe");
|
||||
|
||||
set_cloexec(self_pipe[0]);
|
||||
set_cloexec(self_pipe[1]);
|
||||
|
||||
sighandle.sa_handler = &sighandler;
|
||||
child_handle.sa_handler = SIG_IGN;
|
||||
|
||||
if (sigaction(SIGTERM, &sighandle, NULL) < 0 ||
|
||||
sigaction(SIGINT, &sighandle, NULL) < 0 ||
|
||||
sigaction(SIGCHLD, &child_handle, NULL) < 0)
|
||||
die("sigaction");
|
||||
|
||||
display = wl_display_connect(NULL);
|
||||
if (!display)
|
||||
die("Failed to connect to a Wayland display.");
|
||||
wl_display_fd = wl_display_get_fd(display);
|
||||
|
||||
wl_list_init(&seats);
|
||||
wl_list_init(&monitors);
|
||||
wl_list_init(&uninitializedOutputs);
|
||||
|
||||
wl_registry *registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
setupFifo();
|
||||
|
||||
globalChecks(); /* Make sure we're ready to start the rest of the program */
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
// Initalize any outputs we got from registry. Then free the outputs.
|
||||
uninitOutput *output, *tmp;
|
||||
wl_list_for_each_safe(output, tmp, &uninitializedOutputs, link) {
|
||||
monitorSetup(output->name, output->output);
|
||||
wl_list_remove(&output->link);
|
||||
free(output);
|
||||
}
|
||||
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
pollfds = ecalloc(POLLFDS, sizeof(*pollfds));
|
||||
|
||||
pollfds[0] = (pollfd) {STDIN_FILENO, POLLIN};
|
||||
pollfds[1] = (pollfd) {wl_display_fd, POLLIN};
|
||||
pollfds[2] = (pollfd) {self_pipe[0], POLLIN};
|
||||
pollfds[3] = (pollfd) {fifo_fd, POLLIN};
|
||||
|
||||
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) < 0)
|
||||
die("O_NONBLOCK");
|
||||
}
|
||||
|
||||
void run(void) {
|
||||
struct pollfd *pollfd;
|
||||
int i, quitting = 0;
|
||||
|
||||
while (!quitting) {
|
||||
flush();
|
||||
if (poll(pollfds, POLLFDS, -1) < 0 && errno != EINTR)
|
||||
die("poll");
|
||||
|
||||
for (i = 0; i < POLLFDS; i++) {
|
||||
pollfd = &pollfds[i];
|
||||
if (pollfd->revents & POLLNVAL)
|
||||
die("POLLNVAL");
|
||||
|
||||
if (pollfd->fd == wl_display_fd) {
|
||||
if ((pollfd->revents & POLLIN) && (wl_display_dispatch(display) < 0))
|
||||
die("wl_display_dispatch");
|
||||
|
||||
if (pollfd->revents & POLLOUT) {
|
||||
pollfd->events = POLLIN;
|
||||
flush();
|
||||
}
|
||||
} else if (pollfd->fd == STDIN_FILENO && (pollfd->revents & POLLIN)) {
|
||||
on_stdin();
|
||||
} else if (pollfd->fd == fifo_fd && (pollfd->revents & POLLIN)) {
|
||||
on_status();
|
||||
} else if (pollfd->fd == self_pipe[0] && (pollfd->revents & POLLIN)) {
|
||||
quitting = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup(void) {
|
||||
if (shm)
|
||||
wl_shm_destroy(shm);
|
||||
if (compositor)
|
||||
wl_compositor_destroy(compositor);
|
||||
if (base)
|
||||
xdg_wm_base_destroy(base);
|
||||
if (shell)
|
||||
zwlr_layer_shell_v1_destroy(shell);
|
||||
if (output_manager)
|
||||
zxdg_output_manager_v1_destroy(output_manager);
|
||||
if (fifo_path) {
|
||||
unlink(fifo_path);
|
||||
remove(fifo_path);
|
||||
}
|
||||
if (file)
|
||||
fclose(file);
|
||||
if (display)
|
||||
wl_display_disconnect(display);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int opt; // Just char for parsing args
|
||||
while ((opt = getopt(argc, argv, "vh")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
printf("Usage: [-h] [-v]\n");
|
||||
printf(" -h: show this\n");
|
||||
printf(" -v: get version\n");
|
||||
exit(0);
|
||||
|
||||
case 'v':
|
||||
printf("A Version");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
setup();
|
||||
run();
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void die(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "error: ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
|
||||
fputc(' ', stderr);
|
||||
perror(NULL);
|
||||
|
||||
} else {
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
cleanup();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void* ecalloc(size_t amnt, size_t size) {
|
||||
void *p;
|
||||
|
||||
if (!(p = calloc(amnt, size))) {
|
||||
die("calloc did not allocate");
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void _logf(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(file, fmt, ap);
|
||||
fflush(file);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void logln(const char* str) {
|
||||
fprintf(file, "%s\n", str);
|
||||
fflush(file);
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "shm.h"
|
||||
|
||||
/* For unmapping the mapped memory when we're finished with the shared memory. */
|
||||
typedef struct MemoryMapping {
|
||||
void* ptr;
|
||||
int size;
|
||||
} MemoryMapping;
|
||||
|
||||
/* To help us keep track of our wayland buffers and their data. */
|
||||
typedef struct Buffer {
|
||||
wl_buffer* buffer;
|
||||
uint8_t* buffer_ptr;
|
||||
} Buffer;
|
||||
|
||||
struct ShmPriv {
|
||||
MemoryMapping* memory;
|
||||
Buffer buffers[2];
|
||||
int current; // Since we hold multiple buffers we need to know which we're currently using.
|
||||
};
|
||||
|
||||
static MemoryMapping* memory_mapping_create(int fd, int pool_size);
|
||||
void memory_mapping_destroy(MemoryMapping* map);
|
||||
|
||||
static Buffer buffer_create(MemoryMapping* memmap, wl_shm_pool* shm, int fd, int width, int height, int offset, wl_shm_format format);
|
||||
static void buffer_destroy(Buffer* buf);
|
||||
|
||||
static int allocate_shm(int size);
|
||||
|
||||
static const int buffer_amnt = 2;
|
||||
int allocate_shm(int size) {
|
||||
char name[] = "wl_shm";
|
||||
int fd;
|
||||
|
||||
if ((fd = shm_open(name, O_CREAT | O_RDWR | O_EXCL, 0600)) < 0) {
|
||||
die("shm_open when allocating shm");
|
||||
}
|
||||
shm_unlink(name);
|
||||
if (ftruncate(fd, size) < 0) {
|
||||
die("ftruncate when allocating shm");
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
MemoryMapping* memory_mapping_create(int fd, int pool_size) {
|
||||
MemoryMapping* map = ecalloc(1, sizeof(MemoryMapping));
|
||||
void* ptr = mmap(NULL, pool_size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (ptr == MAP_FAILED || !ptr) {
|
||||
close(fd);
|
||||
die("MAP_FAILED");
|
||||
}
|
||||
|
||||
map->ptr = ptr;
|
||||
map->size = pool_size;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void memory_mapping_destroy(MemoryMapping* map) {
|
||||
munmap(map->ptr, map->size);
|
||||
free(map);
|
||||
}
|
||||
|
||||
Buffer buffer_create(MemoryMapping* memmap, wl_shm_pool* pool, int fd, int width, int height, int offset, wl_shm_format format) {
|
||||
int stride = width * 4,
|
||||
pool_size = height * stride;
|
||||
Buffer buffer;
|
||||
|
||||
if (!memmap)
|
||||
die("memmap is null");
|
||||
|
||||
wl_buffer* wl_buf = wl_shm_pool_create_buffer(pool, offset, width, height, stride, format);
|
||||
|
||||
buffer.buffer = wl_buf;
|
||||
buffer.buffer_ptr = memmap->ptr+offset;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void buffer_destroy(Buffer* buffer) {
|
||||
wl_buffer_destroy(buffer->buffer);
|
||||
}
|
||||
|
||||
Shm* shm_create(int w, int h, wl_shm_format format) {
|
||||
Shm* _shm = calloc(1, sizeof(Shm));
|
||||
ShmPriv* priv = calloc(1, sizeof(ShmPriv));
|
||||
MemoryMapping* memory;
|
||||
int i, offset,
|
||||
stride = w * 4,
|
||||
size = stride * h,
|
||||
total = size * buffer_amnt;
|
||||
int fd = allocate_shm(total);
|
||||
|
||||
memory = memory_mapping_create(fd, total);
|
||||
wl_shm_pool* pool = wl_shm_create_pool(shm, fd, total);
|
||||
for (i = 0; i < buffer_amnt; i++) {
|
||||
offset = size*i;
|
||||
priv->buffers[i] = buffer_create(memory, pool, fd, w, h, offset, format);
|
||||
}
|
||||
close(fd);
|
||||
wl_shm_pool_destroy(pool);
|
||||
|
||||
priv->memory = memory;
|
||||
priv->current = 0;
|
||||
|
||||
_shm->priv = priv;
|
||||
_shm->height = h;
|
||||
_shm->width = w;
|
||||
_shm->stride = stride;
|
||||
|
||||
return _shm;
|
||||
}
|
||||
|
||||
void shm_destroy(Shm* shm) {
|
||||
uint i;
|
||||
if (shm->priv->memory) {
|
||||
memory_mapping_destroy(shm->priv->memory);
|
||||
}
|
||||
|
||||
for (i = 0; i < buffer_amnt; i++) { // REVIEW this may cause problems
|
||||
if (&shm->priv->buffers[i]) {
|
||||
buffer_destroy(&shm->priv->buffers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* shm_data(Shm *shm) {
|
||||
return shm->priv->buffers[shm->priv->current].buffer_ptr;
|
||||
}
|
||||
|
||||
wl_buffer* shm_buffer(Shm *shm) {
|
||||
return shm->priv->buffers[shm->priv->current].buffer;
|
||||
}
|
||||
|
||||
void shm_flip(Shm *shm) {
|
||||
shm->priv->current = 1-shm->priv->current;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef SHM_H_
|
||||
#define SHM_H_
|
||||
#include "common.h"
|
||||
#include <stdint.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
|
||||
typedef struct ShmPriv ShmPriv;
|
||||
|
||||
struct Shm {
|
||||
int width;
|
||||
int height;
|
||||
int stride;
|
||||
|
||||
ShmPriv* priv;
|
||||
};
|
||||
typedef struct Shm Shm;
|
||||
|
||||
Shm* shm_create(int w, int h, wl_shm_format format);
|
||||
void shm_destroy(Shm* shm);
|
||||
uint8_t* shm_data(Shm* shm);
|
||||
wl_buffer* shm_buffer(Shm* shm);
|
||||
void shm_flip(Shm* shm);
|
||||
|
||||
#endif // SHM_H_
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef UTIL_H_
|
||||
#define UTIL_H_
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
void* ptr;
|
||||
uint size;
|
||||
} Stack;
|
||||
|
||||
#define stack_for_each(pos, stack) \
|
||||
for (pos = (stack)->data); \
|
||||
(const char*) pos < ((const char*) (stack)->data + (stack)->size); \
|
||||
(pos)++)
|
||||
|
||||
|
||||
inline void stack_init(Stack* stack) {
|
||||
stack->ptr = NULL;
|
||||
stack->size = 0;
|
||||
}
|
||||
|
||||
void* stack_end(Stack* stack);
|
||||
void* stack_push(Stack* stack);
|
||||
|
||||
#endif // UTIL_H_
|
||||
|
|
@ -0,0 +1,706 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
#ifndef WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_wlr_layer_shell_unstable_v1 The wlr_layer_shell_unstable_v1 protocol
|
||||
* @section page_ifaces_wlr_layer_shell_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zwlr_layer_shell_v1 - create surfaces that are layers of the desktop
|
||||
* - @subpage page_iface_zwlr_layer_surface_v1 - layer metadata interface
|
||||
* @section page_copyright_wlr_layer_shell_unstable_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* Copyright © 2017 Drew DeVault
|
||||
*
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
struct wl_output;
|
||||
struct wl_surface;
|
||||
struct xdg_popup;
|
||||
struct zwlr_layer_shell_v1;
|
||||
struct zwlr_layer_surface_v1;
|
||||
|
||||
#ifndef ZWLR_LAYER_SHELL_V1_INTERFACE
|
||||
#define ZWLR_LAYER_SHELL_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zwlr_layer_shell_v1 zwlr_layer_shell_v1
|
||||
* @section page_iface_zwlr_layer_shell_v1_desc Description
|
||||
*
|
||||
* Clients can use this interface to assign the surface_layer role to
|
||||
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
* rendered with a defined z-depth respective to each other. They may also be
|
||||
* anchored to the edges and corners of a screen and specify input handling
|
||||
* semantics. This interface should be suitable for the implementation of
|
||||
* many desktop shell components, and a broad number of other applications
|
||||
* that interact with the desktop.
|
||||
* @section page_iface_zwlr_layer_shell_v1_api API
|
||||
* See @ref iface_zwlr_layer_shell_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zwlr_layer_shell_v1 The zwlr_layer_shell_v1 interface
|
||||
*
|
||||
* Clients can use this interface to assign the surface_layer role to
|
||||
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
* rendered with a defined z-depth respective to each other. They may also be
|
||||
* anchored to the edges and corners of a screen and specify input handling
|
||||
* semantics. This interface should be suitable for the implementation of
|
||||
* many desktop shell components, and a broad number of other applications
|
||||
* that interact with the desktop.
|
||||
*/
|
||||
extern const struct wl_interface zwlr_layer_shell_v1_interface;
|
||||
#endif
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_INTERFACE
|
||||
#define ZWLR_LAYER_SURFACE_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zwlr_layer_surface_v1 zwlr_layer_surface_v1
|
||||
* @section page_iface_zwlr_layer_surface_v1_desc Description
|
||||
*
|
||||
* An interface that may be implemented by a wl_surface, for surfaces that
|
||||
* are designed to be rendered as a layer of a stacked desktop-like
|
||||
* environment.
|
||||
*
|
||||
* Layer surface state (layer, size, anchor, exclusive zone,
|
||||
* margin, interactivity) is double-buffered, and will be applied at the
|
||||
* time wl_surface.commit of the corresponding wl_surface is called.
|
||||
*
|
||||
* Attaching a null buffer to a layer surface unmaps it.
|
||||
*
|
||||
* Unmapping a layer_surface means that the surface cannot be shown by the
|
||||
* compositor until it is explicitly mapped again. The layer_surface
|
||||
* returns to the state it had right after layer_shell.get_layer_surface.
|
||||
* The client can re-map the surface by performing a commit without any
|
||||
* buffer attached, waiting for a configure event and handling it as usual.
|
||||
* @section page_iface_zwlr_layer_surface_v1_api API
|
||||
* See @ref iface_zwlr_layer_surface_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zwlr_layer_surface_v1 The zwlr_layer_surface_v1 interface
|
||||
*
|
||||
* An interface that may be implemented by a wl_surface, for surfaces that
|
||||
* are designed to be rendered as a layer of a stacked desktop-like
|
||||
* environment.
|
||||
*
|
||||
* Layer surface state (layer, size, anchor, exclusive zone,
|
||||
* margin, interactivity) is double-buffered, and will be applied at the
|
||||
* time wl_surface.commit of the corresponding wl_surface is called.
|
||||
*
|
||||
* Attaching a null buffer to a layer surface unmaps it.
|
||||
*
|
||||
* Unmapping a layer_surface means that the surface cannot be shown by the
|
||||
* compositor until it is explicitly mapped again. The layer_surface
|
||||
* returns to the state it had right after layer_shell.get_layer_surface.
|
||||
* The client can re-map the surface by performing a commit without any
|
||||
* buffer attached, waiting for a configure event and handling it as usual.
|
||||
*/
|
||||
extern const struct wl_interface zwlr_layer_surface_v1_interface;
|
||||
#endif
|
||||
|
||||
#ifndef ZWLR_LAYER_SHELL_V1_ERROR_ENUM
|
||||
#define ZWLR_LAYER_SHELL_V1_ERROR_ENUM
|
||||
enum zwlr_layer_shell_v1_error {
|
||||
/**
|
||||
* wl_surface has another role
|
||||
*/
|
||||
ZWLR_LAYER_SHELL_V1_ERROR_ROLE = 0,
|
||||
/**
|
||||
* layer value is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER = 1,
|
||||
/**
|
||||
* wl_surface has a buffer attached or committed
|
||||
*/
|
||||
ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED = 2,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SHELL_V1_ERROR_ENUM */
|
||||
|
||||
#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||
#define ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
* available layers for surfaces
|
||||
*
|
||||
* These values indicate which layers a surface can be rendered in. They
|
||||
* are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||
* will typically be rendered between the bottom and top layers.
|
||||
* Fullscreen shell surfaces are typically rendered at the top layer.
|
||||
* Multiple surfaces can share a single layer, and ordering within a
|
||||
* single layer is undefined.
|
||||
*/
|
||||
enum zwlr_layer_shell_v1_layer {
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND = 0,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM = 1,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_TOP = 2,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY = 3,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SHELL_V1_LAYER_ENUM */
|
||||
|
||||
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE 0
|
||||
#define ZWLR_LAYER_SHELL_V1_DESTROY 1
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION 3
|
||||
|
||||
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||
static inline void
|
||||
zwlr_layer_shell_v1_set_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_shell_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||
static inline void *
|
||||
zwlr_layer_shell_v1_get_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zwlr_layer_shell_v1_get_version(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
*
|
||||
* Create a layer surface for an existing surface. This assigns the role of
|
||||
* layer_surface, or raises a protocol error if another role is already
|
||||
* assigned.
|
||||
*
|
||||
* Creating a layer surface from a wl_surface which has a buffer attached
|
||||
* or committed is a client error, and any attempts by a client to attach
|
||||
* or manipulate a buffer prior to the first layer_surface.configure call
|
||||
* must also be treated as errors.
|
||||
*
|
||||
* After creating a layer_surface object and setting it up, the client
|
||||
* must perform an initial commit without any buffer attached.
|
||||
* The compositor will reply with a layer_surface.configure event.
|
||||
* The client must acknowledge it and is then allowed to attach a buffer
|
||||
* to map the surface.
|
||||
*
|
||||
* You may pass NULL for output to allow the compositor to decide which
|
||||
* output to use. Generally this will be the one that the user most
|
||||
* recently interacted with.
|
||||
*
|
||||
* Clients can specify a namespace that defines the purpose of the layer
|
||||
* surface.
|
||||
*/
|
||||
static inline struct zwlr_layer_surface_v1 *
|
||||
zwlr_layer_shell_v1_get_layer_surface(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, struct wl_surface *surface, struct wl_output *output, uint32_t layer, const char *name_space)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_shell_v1,
|
||||
ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE, &zwlr_layer_surface_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1), 0, NULL, surface, output, layer, name_space);
|
||||
|
||||
return (struct zwlr_layer_surface_v1 *) id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
*
|
||||
* This request indicates that the client will not use the layer_shell
|
||||
* object any more. Objects that have been created through this instance
|
||||
* are not affected.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_shell_v1_destroy(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_shell_v1,
|
||||
ZWLR_LAYER_SHELL_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ENUM
|
||||
#define ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ENUM
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
* types of keyboard interaction possible for a layer shell surface
|
||||
*
|
||||
* Types of keyboard interaction possible for layer shell surfaces. The
|
||||
* rationale for this is twofold: (1) some applications are not interested
|
||||
* in keyboard events and not allowing them to be focused can improve the
|
||||
* desktop experience; (2) some applications will want to take exclusive
|
||||
* keyboard focus.
|
||||
*/
|
||||
enum zwlr_layer_surface_v1_keyboard_interactivity {
|
||||
/**
|
||||
* no keyboard focus is possible
|
||||
*
|
||||
* This value indicates that this surface is not interested in
|
||||
* keyboard events and the compositor should never assign it the
|
||||
* keyboard focus.
|
||||
*
|
||||
* This is the default value, set for newly created layer shell
|
||||
* surfaces.
|
||||
*
|
||||
* This is useful for e.g. desktop widgets that display information
|
||||
* or only have interaction with non-keyboard input devices.
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE = 0,
|
||||
/**
|
||||
* request exclusive keyboard focus
|
||||
*
|
||||
* Request exclusive keyboard focus if this surface is above the
|
||||
* shell surface layer.
|
||||
*
|
||||
* For the top and overlay layers, the seat will always give
|
||||
* exclusive keyboard focus to the top-most layer which has
|
||||
* keyboard interactivity set to exclusive. If this layer contains
|
||||
* multiple surfaces with keyboard interactivity set to exclusive,
|
||||
* the compositor determines the one receiving keyboard events in
|
||||
* an implementation- defined manner. In this case, no guarantee is
|
||||
* made when this surface will receive keyboard focus (if ever).
|
||||
*
|
||||
* For the bottom and background layers, the compositor is allowed
|
||||
* to use normal focus semantics.
|
||||
*
|
||||
* This setting is mainly intended for applications that need to
|
||||
* ensure they receive all keyboard events, such as a lock screen
|
||||
* or a password prompt.
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE = 1,
|
||||
/**
|
||||
* request regular keyboard focus semantics
|
||||
*
|
||||
* This requests the compositor to allow this surface to be
|
||||
* focused and unfocused by the user in an implementation-defined
|
||||
* manner. The user should be able to unfocus this surface even
|
||||
* regardless of the layer it is on.
|
||||
*
|
||||
* Typically, the compositor will want to use its normal mechanism
|
||||
* to manage keyboard focus between layer shell surfaces with this
|
||||
* setting and regular toplevels on the desktop layer (e.g. click
|
||||
* to focus). Nevertheless, it is possible for a compositor to
|
||||
* require a special interaction to focus or unfocus layer shell
|
||||
* surfaces (e.g. requiring a click even if focus follows the mouse
|
||||
* normally, or providing a keybinding to switch focus between
|
||||
* layers).
|
||||
*
|
||||
* This setting is mainly intended for desktop shell components
|
||||
* (e.g. panels) that allow keyboard interaction. Using this option
|
||||
* can allow implementing a desktop shell that can be fully usable
|
||||
* without the mouse.
|
||||
* @since 4
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND = 2,
|
||||
};
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND_SINCE_VERSION 4
|
||||
#endif /* ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ENUM */
|
||||
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
|
||||
#define ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
|
||||
enum zwlr_layer_surface_v1_error {
|
||||
/**
|
||||
* provided surface state is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SURFACE_STATE = 0,
|
||||
/**
|
||||
* size is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE = 1,
|
||||
/**
|
||||
* anchor bitfield is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_ANCHOR = 2,
|
||||
/**
|
||||
* keyboard interactivity is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_KEYBOARD_INTERACTIVITY = 3,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SURFACE_V1_ERROR_ENUM */
|
||||
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
|
||||
#define ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
|
||||
enum zwlr_layer_surface_v1_anchor {
|
||||
/**
|
||||
* the top edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP = 1,
|
||||
/**
|
||||
* the bottom edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM = 2,
|
||||
/**
|
||||
* the left edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT = 4,
|
||||
/**
|
||||
* the right edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT = 8,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
* @struct zwlr_layer_surface_v1_listener
|
||||
*/
|
||||
struct zwlr_layer_surface_v1_listener {
|
||||
/**
|
||||
* suggest a surface change
|
||||
*
|
||||
* The configure event asks the client to resize its surface.
|
||||
*
|
||||
* Clients should arrange their surface for the new states, and
|
||||
* then send an ack_configure request with the serial sent in this
|
||||
* configure event at some point before committing the new surface.
|
||||
*
|
||||
* The client is free to dismiss all but the last configure event
|
||||
* it received.
|
||||
*
|
||||
* The width and height arguments specify the size of the window in
|
||||
* surface-local coordinates.
|
||||
*
|
||||
* The size is a hint, in the sense that the client is free to
|
||||
* ignore it if it doesn't resize, pick a smaller size (to satisfy
|
||||
* aspect ratio or resize in steps of NxM pixels). If the client
|
||||
* picks a smaller size and is anchored to two opposite anchors
|
||||
* (e.g. 'top' and 'bottom'), the surface will be centered on this
|
||||
* axis.
|
||||
*
|
||||
* If the width or height arguments are zero, it means the client
|
||||
* should decide its own window dimension.
|
||||
*/
|
||||
void (*configure)(void *data,
|
||||
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
|
||||
uint32_t serial,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
/**
|
||||
* surface should be closed
|
||||
*
|
||||
* The closed event is sent by the compositor when the surface
|
||||
* will no longer be shown. The output may have been destroyed or
|
||||
* the user may have asked for it to be removed. Further changes to
|
||||
* the surface will be ignored. The client should destroy the
|
||||
* resource after receiving this event, and create a new surface if
|
||||
* they so choose.
|
||||
*/
|
||||
void (*closed)(void *data,
|
||||
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
static inline int
|
||||
zwlr_layer_surface_v1_add_listener(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
|
||||
const struct zwlr_layer_surface_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE 0
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR 1
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE 2
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN 3
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY 4
|
||||
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP 5
|
||||
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE 6
|
||||
#define ZWLR_LAYER_SURFACE_V1_DESTROY 7
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_LAYER 8
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_CONFIGURE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_CLOSED_SINCE_VERSION 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_DESTROY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION 2
|
||||
|
||||
/** @ingroup iface_zwlr_layer_surface_v1 */
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_surface_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zwlr_layer_surface_v1 */
|
||||
static inline void *
|
||||
zwlr_layer_surface_v1_get_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zwlr_layer_surface_v1_get_version(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Sets the size of the surface in surface-local coordinates. The
|
||||
* compositor will display the surface centered with respect to its
|
||||
* anchors.
|
||||
*
|
||||
* If you pass 0 for either value, the compositor will assign it and
|
||||
* inform you of the assignment in the configure event. You must set your
|
||||
* anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||
* protocol error. Both values are 0 by default.
|
||||
*
|
||||
* Size is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_size(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t width, uint32_t height)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Requests that the compositor anchor the surface to the specified edges
|
||||
* and corners. If two orthogonal edges are specified (e.g. 'top' and
|
||||
* 'left'), then the anchor point will be the intersection of the edges
|
||||
* (e.g. the top left corner of the output); otherwise the anchor point
|
||||
* will be centered on that edge, or in the center if none is specified.
|
||||
*
|
||||
* Anchor is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_anchor(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t anchor)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, anchor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Requests that the compositor avoids occluding an area with other
|
||||
* surfaces. The compositor's use of this information is
|
||||
* implementation-dependent - do not assume that this region will not
|
||||
* actually be occluded.
|
||||
*
|
||||
* A positive value is only meaningful if the surface is anchored to one
|
||||
* edge or an edge and both perpendicular edges. If the surface is not
|
||||
* anchored, anchored to only two perpendicular edges (a corner), anchored
|
||||
* to only two parallel edges or anchored to all edges, a positive value
|
||||
* will be treated the same as zero.
|
||||
*
|
||||
* A positive zone is the distance from the edge in surface-local
|
||||
* coordinates to consider exclusive.
|
||||
*
|
||||
* Surfaces that do not wish to have an exclusive zone may instead specify
|
||||
* how they should interact with surfaces that do. If set to zero, the
|
||||
* surface indicates that it would like to be moved to avoid occluding
|
||||
* surfaces with a positive exclusive zone. If set to -1, the surface
|
||||
* indicates that it would not like to be moved to accommodate for other
|
||||
* surfaces, and the compositor should extend it all the way to the edges
|
||||
* it is anchored to.
|
||||
*
|
||||
* For example, a panel might set its exclusive zone to 10, so that
|
||||
* maximized shell surfaces are not shown on top of it. A notification
|
||||
* might set its exclusive zone to 0, so that it is moved to avoid
|
||||
* occluding the panel, but shell surfaces are shown underneath it. A
|
||||
* wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||
* they stretch below or over the panel.
|
||||
*
|
||||
* The default value is 0.
|
||||
*
|
||||
* Exclusive zone is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t zone)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, zone);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Requests that the surface be placed some distance away from the anchor
|
||||
* point on the output, in surface-local coordinates. Setting this value
|
||||
* for edges you are not anchored to has no effect.
|
||||
*
|
||||
* The exclusive zone includes the margin.
|
||||
*
|
||||
* Margin is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_margin(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t top, int32_t right, int32_t bottom, int32_t left)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_MARGIN, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, top, right, bottom, left);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Set how keyboard events are delivered to this surface. By default,
|
||||
* layer shell surfaces do not receive keyboard events; this request can
|
||||
* be used to change this.
|
||||
*
|
||||
* This setting is inherited by child surfaces set by the get_popup
|
||||
* request.
|
||||
*
|
||||
* Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
* you do not want to receive them, set the input region on your surface
|
||||
* to an empty region.
|
||||
*
|
||||
* Keyboard interactivity is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t keyboard_interactivity)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, keyboard_interactivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||
* should have been created via xdg_surface::get_popup with the parent set
|
||||
* to NULL, and this request must be invoked before committing the popup's
|
||||
* initial state.
|
||||
*
|
||||
* See the documentation of xdg_popup for more details about what an
|
||||
* xdg_popup is and how it is used.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_get_popup(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, struct xdg_popup *popup)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_GET_POPUP, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, popup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* When a configure event is received, if a client commits the
|
||||
* surface in response to the configure event, then the client
|
||||
* must make an ack_configure request sometime before the commit
|
||||
* request, passing along the serial of the configure event.
|
||||
*
|
||||
* If the client receives multiple configure events before it
|
||||
* can respond to one, it only has to ack the last configure event.
|
||||
*
|
||||
* A client is not required to commit immediately after sending
|
||||
* an ack_configure request - it may even ack_configure several times
|
||||
* before its next surface commit.
|
||||
*
|
||||
* A client may send multiple ack_configure requests before committing, but
|
||||
* only the last request sent before a commit indicates which configure
|
||||
* event the client really is responding to.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_ack_configure(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, serial);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* This request destroys the layer surface.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_destroy(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Change the layer that the surface is rendered on.
|
||||
*
|
||||
* Layer is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_layer(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t layer)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_LAYER, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, layer);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2017 Drew DeVault
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface zwlr_layer_surface_v1_interface;
|
||||
|
||||
static const struct wl_interface *wlr_layer_shell_unstable_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&zwlr_layer_surface_v1_interface,
|
||||
&wl_surface_interface,
|
||||
&wl_output_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_popup_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message zwlr_layer_shell_v1_requests[] = {
|
||||
{ "get_layer_surface", "no?ous", wlr_layer_shell_unstable_v1_types + 4 },
|
||||
{ "destroy", "3", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface zwlr_layer_shell_v1_interface = {
|
||||
"zwlr_layer_shell_v1", 4,
|
||||
2, zwlr_layer_shell_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message zwlr_layer_surface_v1_requests[] = {
|
||||
{ "set_size", "uu", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_anchor", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_exclusive_zone", "i", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_margin", "iiii", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_keyboard_interactivity", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "get_popup", "o", wlr_layer_shell_unstable_v1_types + 9 },
|
||||
{ "ack_configure", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "destroy", "", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_layer", "2u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message zwlr_layer_surface_v1_events[] = {
|
||||
{ "configure", "uuu", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "closed", "", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface zwlr_layer_surface_v1_interface = {
|
||||
"zwlr_layer_surface_v1", 4,
|
||||
9, zwlr_layer_surface_v1_requests,
|
||||
2, zwlr_layer_surface_v1_events,
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,411 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
#ifndef XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol
|
||||
* Protocol to describe output regions
|
||||
*
|
||||
* @section page_desc_xdg_output_unstable_v1 Description
|
||||
*
|
||||
* This protocol aims at describing outputs in a way which is more in line
|
||||
* with the concept of an output on desktop oriented systems.
|
||||
*
|
||||
* Some information are more specific to the concept of an output for
|
||||
* a desktop oriented system and may not make sense in other applications,
|
||||
* such as IVI systems for example.
|
||||
*
|
||||
* Typically, the global compositor space on a desktop system is made of
|
||||
* a contiguous or overlapping set of rectangular regions.
|
||||
*
|
||||
* Some of the information provided in this protocol might be identical
|
||||
* to their counterparts already available from wl_output, in which case
|
||||
* the information provided by this protocol should be preferred to their
|
||||
* equivalent in wl_output. The goal is to move the desktop specific
|
||||
* concepts (such as output location within the global compositor space,
|
||||
* the connector name and types, etc.) out of the core wl_output protocol.
|
||||
*
|
||||
* Warning! The protocol described in this file is experimental and
|
||||
* backward incompatible changes may be made. Backward compatible
|
||||
* changes may be added together with the corresponding interface
|
||||
* version bump.
|
||||
* Backward incompatible changes are done by bumping the version
|
||||
* number in the protocol and interface names and resetting the
|
||||
* interface version. Once the protocol is to be declared stable,
|
||||
* the 'z' prefix and the version number in the protocol and
|
||||
* interface names are removed and the interface version number is
|
||||
* reset.
|
||||
*
|
||||
* @section page_ifaces_xdg_output_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects
|
||||
* - @subpage page_iface_zxdg_output_v1 - compositor logical output region
|
||||
* @section page_copyright_xdg_output_unstable_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
* </pre>
|
||||
*/
|
||||
struct wl_output;
|
||||
struct zxdg_output_manager_v1;
|
||||
struct zxdg_output_v1;
|
||||
|
||||
#ifndef ZXDG_OUTPUT_MANAGER_V1_INTERFACE
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1
|
||||
* @section page_iface_zxdg_output_manager_v1_desc Description
|
||||
*
|
||||
* A global factory interface for xdg_output objects.
|
||||
* @section page_iface_zxdg_output_manager_v1_api API
|
||||
* See @ref iface_zxdg_output_manager_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface
|
||||
*
|
||||
* A global factory interface for xdg_output objects.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_output_manager_v1_interface;
|
||||
#endif
|
||||
#ifndef ZXDG_OUTPUT_V1_INTERFACE
|
||||
#define ZXDG_OUTPUT_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_output_v1 zxdg_output_v1
|
||||
* @section page_iface_zxdg_output_v1_desc Description
|
||||
*
|
||||
* An xdg_output describes part of the compositor geometry.
|
||||
*
|
||||
* This typically corresponds to a monitor that displays part of the
|
||||
* compositor space.
|
||||
*
|
||||
* For objects version 3 onwards, after all xdg_output properties have been
|
||||
* sent (when the object is created and when properties are updated), a
|
||||
* wl_output.done event is sent. This allows changes to the output
|
||||
* properties to be seen as atomic, even if they happen via multiple events.
|
||||
* @section page_iface_zxdg_output_v1_api API
|
||||
* See @ref iface_zxdg_output_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface
|
||||
*
|
||||
* An xdg_output describes part of the compositor geometry.
|
||||
*
|
||||
* This typically corresponds to a monitor that displays part of the
|
||||
* compositor space.
|
||||
*
|
||||
* For objects version 3 onwards, after all xdg_output properties have been
|
||||
* sent (when the object is created and when properties are updated), a
|
||||
* wl_output.done event is sent. This allows changes to the output
|
||||
* properties to be seen as atomic, even if they happen via multiple events.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_output_v1_interface;
|
||||
#endif
|
||||
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zxdg_output_manager_v1 */
|
||||
static inline void
|
||||
zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zxdg_output_manager_v1 */
|
||||
static inline void *
|
||||
zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*
|
||||
* Using this request a client can tell the server that it is not
|
||||
* going to use the xdg_output_manager object anymore.
|
||||
*
|
||||
* Any objects already created through this instance are not affected.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1,
|
||||
ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*
|
||||
* This creates a new xdg_output object for the given wl_output.
|
||||
*/
|
||||
static inline struct zxdg_output_v1 *
|
||||
zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1,
|
||||
ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output);
|
||||
|
||||
return (struct zxdg_output_v1 *) id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
* @struct zxdg_output_v1_listener
|
||||
*/
|
||||
struct zxdg_output_v1_listener {
|
||||
/**
|
||||
* position of the output within the global compositor space
|
||||
*
|
||||
* The position event describes the location of the wl_output
|
||||
* within the global compositor space.
|
||||
*
|
||||
* The logical_position event is sent after creating an xdg_output
|
||||
* (see xdg_output_manager.get_xdg_output) and whenever the
|
||||
* location of the output changes within the global compositor
|
||||
* space.
|
||||
* @param x x position within the global compositor space
|
||||
* @param y y position within the global compositor space
|
||||
*/
|
||||
void (*logical_position)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
int32_t x,
|
||||
int32_t y);
|
||||
/**
|
||||
* size of the output in the global compositor space
|
||||
*
|
||||
* The logical_size event describes the size of the output in the
|
||||
* global compositor space.
|
||||
*
|
||||
* For example, a surface without any buffer scale, transformation
|
||||
* nor rotation set, with the size matching the logical_size will
|
||||
* have the same size as the corresponding output when displayed.
|
||||
*
|
||||
* Most regular Wayland clients should not pay attention to the
|
||||
* logical size and would rather rely on xdg_shell interfaces.
|
||||
*
|
||||
* Some clients such as Xwayland, however, need this to configure
|
||||
* their surfaces in the global compositor space as the compositor
|
||||
* may apply a different scale from what is advertised by the
|
||||
* output scaling property (to achieve fractional scaling, for
|
||||
* example).
|
||||
*
|
||||
* For example, for a wl_output mode 3840×2160 and a scale factor
|
||||
* 2:
|
||||
*
|
||||
* - A compositor not scaling the surface buffers will advertise a
|
||||
* logical size of 3840×2160,
|
||||
*
|
||||
* - A compositor automatically scaling the surface buffers will
|
||||
* advertise a logical size of 1920×1080,
|
||||
*
|
||||
* - A compositor using a fractional scale of 1.5 will advertise a
|
||||
* logical size of 2560×1440.
|
||||
*
|
||||
* For example, for a wl_output mode 1920×1080 and a 90 degree
|
||||
* rotation, the compositor will advertise a logical size of
|
||||
* 1080x1920.
|
||||
*
|
||||
* The logical_size event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output) and whenever the logical size
|
||||
* of the output changes, either as a result of a change in the
|
||||
* applied scale or because of a change in the corresponding output
|
||||
* mode(see wl_output.mode) or transform (see wl_output.transform).
|
||||
* @param width width in global compositor space
|
||||
* @param height height in global compositor space
|
||||
*/
|
||||
void (*logical_size)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* all information about the output have been sent
|
||||
*
|
||||
* This event is sent after all other properties of an xdg_output
|
||||
* have been sent.
|
||||
*
|
||||
* This allows changes to the xdg_output properties to be seen as
|
||||
* atomic, even if they happen via multiple events.
|
||||
*
|
||||
* For objects version 3 onwards, this event is deprecated.
|
||||
* Compositors are not required to send it anymore and must send
|
||||
* wl_output.done instead.
|
||||
*/
|
||||
void (*done)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1);
|
||||
/**
|
||||
* name of this output
|
||||
*
|
||||
* Many compositors will assign names to their outputs, show them
|
||||
* to the user, allow them to be configured by name, etc. The
|
||||
* client may wish to know this name as well to offer the user
|
||||
* similar behaviors.
|
||||
*
|
||||
* The naming convention is compositor defined, but limited to
|
||||
* alphanumeric characters and dashes (-). Each name is unique
|
||||
* among all wl_output globals, but if a wl_output global is
|
||||
* destroyed the same name may be reused later. The names will also
|
||||
* remain consistent across sessions with the same hardware and
|
||||
* software configuration.
|
||||
*
|
||||
* Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc.
|
||||
* However, do not assume that the name is a reflection of an
|
||||
* underlying DRM connector, X11 connection, etc.
|
||||
*
|
||||
* The name event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output). This event is only sent once
|
||||
* per xdg_output, and the name does not change over the lifetime
|
||||
* of the wl_output global.
|
||||
* @param name output name
|
||||
* @since 2
|
||||
*/
|
||||
void (*name)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const char *name);
|
||||
/**
|
||||
* human-readable description of this output
|
||||
*
|
||||
* Many compositors can produce human-readable descriptions of
|
||||
* their outputs. The client may wish to know this description as
|
||||
* well, to communicate the user for various purposes.
|
||||
*
|
||||
* The description is a UTF-8 string with no convention defined for
|
||||
* its contents. Examples might include 'Foocorp 11" Display' or
|
||||
* 'Virtual X11 output via :1'.
|
||||
*
|
||||
* The description event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output) and whenever the description
|
||||
* changes. The description is optional, and may not be sent at
|
||||
* all.
|
||||
*
|
||||
* For objects of version 2 and lower, this event is only sent once
|
||||
* per xdg_output, and the description does not change over the
|
||||
* lifetime of the wl_output global.
|
||||
* @param description output description
|
||||
* @since 2
|
||||
*/
|
||||
void (*description)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const char *description);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
static inline int
|
||||
zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const struct zxdg_output_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZXDG_OUTPUT_V1_DESTROY 0
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zxdg_output_v1 */
|
||||
static inline void
|
||||
zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zxdg_output_v1 */
|
||||
static inline void *
|
||||
zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*
|
||||
* Using this request a client can tell the server that it is not
|
||||
* going to use the xdg_output object anymore.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1,
|
||||
ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface zxdg_output_v1_interface;
|
||||
|
||||
static const struct wl_interface *xdg_output_unstable_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
&zxdg_output_v1_interface,
|
||||
&wl_output_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_manager_v1_requests[] = {
|
||||
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||
{ "get_xdg_output", "no", xdg_output_unstable_v1_types + 2 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface zxdg_output_manager_v1_interface = {
|
||||
"zxdg_output_manager_v1", 3,
|
||||
2, zxdg_output_manager_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_v1_requests[] = {
|
||||
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_v1_events[] = {
|
||||
{ "logical_position", "ii", xdg_output_unstable_v1_types + 0 },
|
||||
{ "logical_size", "ii", xdg_output_unstable_v1_types + 0 },
|
||||
{ "done", "", xdg_output_unstable_v1_types + 0 },
|
||||
{ "name", "2s", xdg_output_unstable_v1_types + 0 },
|
||||
{ "description", "2s", xdg_output_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface zxdg_output_v1_interface = {
|
||||
"zxdg_output_v1", 3,
|
||||
1, zxdg_output_v1_requests,
|
||||
5, zxdg_output_v1_events,
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,183 @@
|
|||
/* Generated by wayland-scanner 1.21.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2008-2013 Kristian Høgsberg
|
||||
* Copyright © 2013 Rafael Antognolli
|
||||
* Copyright © 2013 Jasper St. Pierre
|
||||
* Copyright © 2010-2013 Intel Corporation
|
||||
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||
* Copyright © 2015-2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||
#endif
|
||||
|
||||
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
#else
|
||||
#define WL_PRIVATE
|
||||
#endif
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface xdg_positioner_interface;
|
||||
extern const struct wl_interface xdg_surface_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *xdg_shell_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&xdg_popup_interface,
|
||||
&xdg_surface_interface,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_output_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||
{ "pong", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_events[] = {
|
||||
{ "ping", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||
"xdg_wm_base", 5,
|
||||
4, xdg_wm_base_requests,
|
||||
1, xdg_wm_base_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_positioner_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||
"xdg_positioner", 5,
|
||||
10, xdg_positioner_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_events[] = {
|
||||
{ "configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||
"xdg_surface", 5,
|
||||
5, xdg_surface_requests,
|
||||
1, xdg_surface_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||
{ "set_title", "s", xdg_shell_types + 0 },
|
||||
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||
{ "move", "ou", xdg_shell_types + 16 },
|
||||
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_events[] = {
|
||||
{ "configure", "iia", xdg_shell_types + 0 },
|
||||
{ "close", "", xdg_shell_types + 0 },
|
||||
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||
"xdg_toplevel", 5,
|
||||
14, xdg_toplevel_requests,
|
||||
4, xdg_toplevel_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "grab", "ou", xdg_shell_types + 22 },
|
||||
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_events[] = {
|
||||
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||
{ "popup_done", "", xdg_shell_types + 0 },
|
||||
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||
"xdg_popup", 5,
|
||||
3, xdg_popup_requests,
|
||||
3, xdg_popup_events,
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue