mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-29 05:40:21 -04:00
init
This commit is contained in:
parent
bb9ae1d13a
commit
af11da1881
29 changed files with 11217 additions and 2 deletions
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Something in dwl isn't working correctly
|
||||||
|
title: ''
|
||||||
|
labels: 'A: bug'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Info
|
||||||
|
dwl version:
|
||||||
|
wlroots version:
|
||||||
|
## Description
|
||||||
|
<!--
|
||||||
|
Only report bugs that can be reproduced on the main line
|
||||||
|
Report patch issues to their respective authors
|
||||||
|
-->
|
||||||
10
.github/ISSUE_TEMPLATE/enhancement-idea.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/enhancement-idea.md
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
name: Enhancement idea
|
||||||
|
about: Suggest a feature or improvement
|
||||||
|
title: ''
|
||||||
|
labels: 'A: enhancement'
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/.cache
|
||||||
|
/.vscode
|
||||||
704
IM.h
Normal file
704
IM.h
Normal file
|
|
@ -0,0 +1,704 @@
|
||||||
|
#ifdef IM
|
||||||
|
#include <assert.h>
|
||||||
|
#include <wlr/types/wlr_text_input_v3.h>
|
||||||
|
#include <wlr/types/wlr_input_method_v2.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The relay structure manages the relationship between text-input and
|
||||||
|
* input_method interfaces on a given seat. Multiple text-input interfaces may
|
||||||
|
* be bound to a relay, but at most one will be focused (receiving events) at
|
||||||
|
* a time. At most one input-method interface may be bound to the seat. The
|
||||||
|
* relay manages life cycle of both sides. When both sides are present and
|
||||||
|
* focused, the relay passes messages between them.
|
||||||
|
*
|
||||||
|
* Text input focus is a subset of keyboard focus - if the text-input is
|
||||||
|
* in the focused state, wl_keyboard sent an enter as well. However, having
|
||||||
|
* wl_keyboard focused doesn't mean that text-input will be focused.
|
||||||
|
*/
|
||||||
|
struct dwl_input_method_relay {
|
||||||
|
struct wl_list text_inputs; // dwl_text_input::link
|
||||||
|
struct wlr_input_method_v2 *input_method; // doesn't have to be present
|
||||||
|
|
||||||
|
struct dwl_input_popup *popup;
|
||||||
|
|
||||||
|
struct wl_listener text_input_new;
|
||||||
|
|
||||||
|
struct wl_listener input_method_new;
|
||||||
|
struct wl_listener input_method_commit;
|
||||||
|
struct wl_listener input_method_destroy;
|
||||||
|
struct wl_listener input_method_new_popup_surface;
|
||||||
|
struct wl_listener input_method_grab_keyboard;
|
||||||
|
struct wl_listener input_method_keyboard_grab_destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dwl_text_input {
|
||||||
|
struct dwl_input_method_relay *relay;
|
||||||
|
|
||||||
|
struct wlr_text_input_v3 *input;
|
||||||
|
// The surface getting seat's focus. Stored for when text-input cannot
|
||||||
|
// be sent an enter event immediately after getting focus, e.g. when
|
||||||
|
// there's no input method available. Cleared once text-input is entered.
|
||||||
|
struct wlr_surface *pending_focused_surface;
|
||||||
|
|
||||||
|
struct wl_list link;
|
||||||
|
|
||||||
|
struct wl_listener pending_focused_surface_destroy;
|
||||||
|
|
||||||
|
struct wl_listener text_input_enable;
|
||||||
|
//struct wl_listener text_input_commit;
|
||||||
|
struct wl_listener text_input_disable;
|
||||||
|
struct wl_listener text_input_destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct dwl_input_popup {
|
||||||
|
struct dwl_input_method_relay *relay;
|
||||||
|
struct wlr_input_popup_surface_v2 *popup_surface;
|
||||||
|
|
||||||
|
//struct wlr_scene_node *scene;
|
||||||
|
struct wlr_scene_tree *scene;
|
||||||
|
//struct wlr_scene_node *scene_surface;
|
||||||
|
struct wlr_scene_tree *scene_surface;
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
bool visible;
|
||||||
|
|
||||||
|
|
||||||
|
struct wl_listener popup_map;
|
||||||
|
struct wl_listener popup_unmap;
|
||||||
|
struct wl_listener popup_destroy;
|
||||||
|
struct wl_listener popup_surface_commit;
|
||||||
|
//struct wl_listener focused_surface_unmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void dwl_input_method_relay_init(struct dwl_input_method_relay *relay);
|
||||||
|
// Updates currently focused surface. Surface must belong to the same
|
||||||
|
// seat.
|
||||||
|
void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay,
|
||||||
|
struct wlr_surface *surface);
|
||||||
|
struct dwl_text_input *dwl_text_input_create(
|
||||||
|
struct dwl_input_method_relay *relay,
|
||||||
|
struct wlr_text_input_v3 *text_input);
|
||||||
|
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data);
|
||||||
|
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener,
|
||||||
|
void *data);
|
||||||
|
static void input_popup_update(struct dwl_input_popup *popup);
|
||||||
|
|
||||||
|
struct wlr_input_method_manager_v2 *input_method_manager;
|
||||||
|
struct wlr_text_input_manager_v3 *text_input_manager;
|
||||||
|
struct dwl_input_method_relay *input_relay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get keyboard grab of the seat from sway_keyboard if we should forward events
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* Returns NULL if the keyboard is not grabbed by an input method,
|
||||||
|
* or if event is from virtual keyboard of the same client as grab.
|
||||||
|
* TODO: see https://github.com/swaywm/wlroots/issues/2322
|
||||||
|
*/
|
||||||
|
static struct wlr_input_method_keyboard_grab_v2 *keyboard_get_im_grab(Keyboard* kb) {
|
||||||
|
struct wlr_input_method_v2 *input_method = input_relay->input_method;
|
||||||
|
struct wlr_virtual_keyboard_v1 *virtual_keyboard =
|
||||||
|
wlr_input_device_get_virtual_keyboard(&kb->wlr_keyboard->base);
|
||||||
|
if (!input_method || !input_method->keyboard_grab || (virtual_keyboard &&
|
||||||
|
wl_resource_get_client(virtual_keyboard->resource) ==
|
||||||
|
wl_resource_get_client(input_method->keyboard_grab->resource))) {
|
||||||
|
if (!input_method){
|
||||||
|
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no input_method");
|
||||||
|
} else if (!input_method->keyboard_grab){
|
||||||
|
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:no input_method->keyboard_grab");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virtual_keyboard) {
|
||||||
|
wlr_log(WLR_DEBUG, "keypress keyboard_get_im_grab return NULL:virtual_keyboard");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return input_method->keyboard_grab;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_grab_keyboard(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
input_method_grab_keyboard);
|
||||||
|
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
||||||
|
|
||||||
|
// send modifier state to grab
|
||||||
|
struct wlr_keyboard *active_keyboard = wlr_seat_get_keyboard(seat);
|
||||||
|
if (active_keyboard){
|
||||||
|
wlr_log(WLR_INFO,"im_grab_keyboard");
|
||||||
|
wlr_input_method_keyboard_grab_v2_set_keyboard(keyboard_grab,active_keyboard);
|
||||||
|
wlr_input_method_keyboard_grab_v2_send_modifiers(keyboard_grab, &active_keyboard->modifiers);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wlr_log(WLR_INFO,"im_grab_keyboard but no active keyboard");
|
||||||
|
|
||||||
|
|
||||||
|
wl_signal_add(&keyboard_grab->events.destroy,
|
||||||
|
&relay->input_method_keyboard_grab_destroy);
|
||||||
|
relay->input_method_keyboard_grab_destroy.notify =
|
||||||
|
handle_im_keyboard_grab_destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_keyboard_grab_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
input_method_keyboard_grab_destroy);
|
||||||
|
struct wlr_input_method_keyboard_grab_v2 *keyboard_grab = data;
|
||||||
|
wlr_log(WLR_DEBUG,"im_keyboard_grab_destroy");
|
||||||
|
wl_list_remove(&relay->input_method_keyboard_grab_destroy.link);
|
||||||
|
if (keyboard_grab->keyboard) {
|
||||||
|
// send modifier state to original client
|
||||||
|
wlr_seat_keyboard_notify_modifiers(keyboard_grab->input_method->seat,
|
||||||
|
&keyboard_grab->keyboard->modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct dwl_text_input *relay_get_focusable_text_input(
|
||||||
|
struct dwl_input_method_relay *relay) {
|
||||||
|
struct dwl_text_input *text_input = NULL;
|
||||||
|
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
||||||
|
if (text_input->pending_focused_surface) {
|
||||||
|
return text_input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dwl_text_input *relay_get_focused_text_input(
|
||||||
|
struct dwl_input_method_relay *relay) {
|
||||||
|
struct dwl_text_input *text_input = NULL;
|
||||||
|
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
||||||
|
if (text_input->input->focused_surface) {
|
||||||
|
return text_input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_commit(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_input_method_v2 *context;
|
||||||
|
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
input_method_commit);
|
||||||
|
|
||||||
|
struct dwl_text_input *text_input = relay_get_focused_text_input(relay);
|
||||||
|
if (!text_input) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context = data;
|
||||||
|
assert(context == relay->input_method);
|
||||||
|
if (context->current.preedit.text) {
|
||||||
|
wlr_text_input_v3_send_preedit_string(text_input->input,
|
||||||
|
context->current.preedit.text,
|
||||||
|
context->current.preedit.cursor_begin,
|
||||||
|
context->current.preedit.cursor_end);
|
||||||
|
wlr_log(WLR_DEBUG,"preedit_text: %s", context->current.preedit.text);
|
||||||
|
}
|
||||||
|
if (context->current.commit_text) {
|
||||||
|
wlr_text_input_v3_send_commit_string(text_input->input,
|
||||||
|
context->current.commit_text);
|
||||||
|
wlr_log(WLR_DEBUG,"commit_text: %s", context->current.commit_text);
|
||||||
|
}
|
||||||
|
if (context->current.delete.before_length
|
||||||
|
|| context->current.delete.after_length) {
|
||||||
|
wlr_text_input_v3_send_delete_surrounding_text(text_input->input,
|
||||||
|
context->current.delete.before_length,
|
||||||
|
context->current.delete.after_length);
|
||||||
|
}
|
||||||
|
wlr_text_input_v3_send_done(text_input->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void text_input_set_pending_focused_surface(
|
||||||
|
struct dwl_text_input *text_input, struct wlr_surface *surface) {
|
||||||
|
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
|
||||||
|
text_input->pending_focused_surface = surface;
|
||||||
|
|
||||||
|
if (surface) {
|
||||||
|
wl_signal_add(&surface->events.destroy,
|
||||||
|
&text_input->pending_focused_surface_destroy);
|
||||||
|
} else {
|
||||||
|
wl_list_init(&text_input->pending_focused_surface_destroy.link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_text_input *text_input;
|
||||||
|
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
input_method_destroy);
|
||||||
|
struct wlr_input_method_v2 *context = data;
|
||||||
|
wlr_log(WLR_INFO,"IM destroy");
|
||||||
|
assert(context == relay->input_method);
|
||||||
|
relay->input_method = NULL;
|
||||||
|
|
||||||
|
text_input = relay_get_focused_text_input(relay);
|
||||||
|
if (text_input) {
|
||||||
|
// keyboard focus is still there, so keep the surface at hand in case
|
||||||
|
// the input method returns
|
||||||
|
text_input_set_pending_focused_surface(text_input,
|
||||||
|
text_input->input->focused_surface);
|
||||||
|
wlr_text_input_v3_send_leave(text_input->input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void relay_send_im_state(struct dwl_input_method_relay *relay,
|
||||||
|
struct wlr_text_input_v3 *input) {
|
||||||
|
struct wlr_input_method_v2 *input_method = relay->input_method;
|
||||||
|
if (!input_method) {
|
||||||
|
wlr_log(WLR_INFO, "Sending IM_DONE but im is gone");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: only send each of those if they were modified
|
||||||
|
wlr_input_method_v2_send_surrounding_text(input_method,
|
||||||
|
input->current.surrounding.text, input->current.surrounding.cursor,
|
||||||
|
input->current.surrounding.anchor);
|
||||||
|
wlr_input_method_v2_send_text_change_cause(input_method,
|
||||||
|
input->current.text_change_cause);
|
||||||
|
wlr_input_method_v2_send_content_type(input_method,
|
||||||
|
input->current.content_type.hint, input->current.content_type.purpose);
|
||||||
|
wlr_input_method_v2_send_done(input_method);
|
||||||
|
// TODO: pass intent, display popup size
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_text_input_enable(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
|
||||||
|
text_input_enable);
|
||||||
|
if (text_input->relay->input_method == NULL) {
|
||||||
|
wlr_log(WLR_INFO, "text_input_enable but input method is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"text_input_enable");
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
wlr_input_method_v2_send_activate(text_input->relay->input_method);
|
||||||
|
wlr_log(WLR_INFO,"input_method activate for xwayland");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
relay_send_im_state(text_input->relay, text_input->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static void handle_text_input_commit(struct wl_listener *listener, */
|
||||||
|
/* void *data) { */
|
||||||
|
/* struct dwl_text_input *text_input = wl_container_of(listener, text_input, */
|
||||||
|
/* text_input_commit); */
|
||||||
|
/* if (!text_input->input->current_enabled) { */
|
||||||
|
/* wlr_log(WLR_INFO, "text_input_commit but not enabled"); */
|
||||||
|
/* return; */
|
||||||
|
/* } */
|
||||||
|
/* if (text_input->relay->input_method == NULL) { */
|
||||||
|
/* wlr_log(WLR_INFO, "text_input_commit but input method is NULL"); */
|
||||||
|
/* return; */
|
||||||
|
/* } */
|
||||||
|
/* wlr_log(WLR_DEBUG, "text_input_commit"); */
|
||||||
|
/* relay_send_im_state(text_input->relay, text_input->input); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
static void relay_disable_text_input(struct dwl_input_method_relay *relay,
|
||||||
|
struct dwl_text_input *text_input) {
|
||||||
|
if (relay->input_method == NULL) {
|
||||||
|
wlr_log(WLR_INFO, "text_input_disable, but input method is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wlr_log(WLR_INFO,"text_input_disable");
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
// https://gitee.com/guyuming76/dwl/commit/59328d6ecbbef1b1cd6e5ea8d90d78ccddd5c263
|
||||||
|
wlr_input_method_v2_send_deactivate(relay->input_method);
|
||||||
|
wlr_log(WLR_INFO,"input_method deactivate for xwayland");
|
||||||
|
#endif
|
||||||
|
//but if you keep the line above while remove the line below, input Chinese in geogebra(xwayland) won't work
|
||||||
|
relay_send_im_state(relay, text_input->input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_text_input_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
|
||||||
|
text_input_destroy);
|
||||||
|
|
||||||
|
if (text_input->input->current_enabled) {
|
||||||
|
wlr_log(WLR_INFO,"text_input_destroy when still enabled");
|
||||||
|
relay_disable_text_input(text_input->relay, text_input);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wlr_log(WLR_INFO,"text_input_destroy");
|
||||||
|
}
|
||||||
|
|
||||||
|
text_input_set_pending_focused_surface(text_input, NULL);
|
||||||
|
//wl_list_remove(&text_input->text_input_commit.link);
|
||||||
|
wl_list_remove(&text_input->text_input_destroy.link);
|
||||||
|
//wl_list_remove(&text_input->text_input_disable.link);
|
||||||
|
wl_list_remove(&text_input->text_input_enable.link);
|
||||||
|
wl_list_remove(&text_input->link);
|
||||||
|
free(text_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_pending_focused_surface_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct dwl_text_input *text_input = wl_container_of(listener, text_input,
|
||||||
|
pending_focused_surface_destroy);
|
||||||
|
struct wlr_surface *surface = data;
|
||||||
|
assert(text_input->pending_focused_surface == surface);
|
||||||
|
text_input->pending_focused_surface = NULL;
|
||||||
|
wl_list_remove(&text_input->pending_focused_surface_destroy.link);
|
||||||
|
wl_list_init(&text_input->pending_focused_surface_destroy.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dwl_text_input *dwl_text_input_create(
|
||||||
|
struct dwl_input_method_relay *relay,
|
||||||
|
struct wlr_text_input_v3 *text_input) {
|
||||||
|
struct dwl_text_input *input;
|
||||||
|
input = calloc(1, sizeof(*input));
|
||||||
|
if (!input) {
|
||||||
|
wlr_log(WLR_ERROR, "dwl_text_input_create calloc failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wlr_log(WLR_INFO, "dwl_text_input_create");
|
||||||
|
input->input = text_input;
|
||||||
|
input->relay = relay;
|
||||||
|
|
||||||
|
wl_list_insert(&relay->text_inputs, &input->link);
|
||||||
|
|
||||||
|
input->text_input_enable.notify = handle_text_input_enable;
|
||||||
|
wl_signal_add(&text_input->events.enable, &input->text_input_enable);
|
||||||
|
|
||||||
|
//input->text_input_commit.notify = handle_text_input_commit;
|
||||||
|
//wl_signal_add(&text_input->events.commit, &input->text_input_commit);
|
||||||
|
|
||||||
|
/* input->text_input_disable.notify = handle_text_input_disable; */
|
||||||
|
/* wl_signal_add(&text_input->events.disable, &input->text_input_disable); */
|
||||||
|
|
||||||
|
input->text_input_destroy.notify = handle_text_input_destroy;
|
||||||
|
wl_signal_add(&text_input->events.destroy, &input->text_input_destroy);
|
||||||
|
|
||||||
|
input->pending_focused_surface_destroy.notify =
|
||||||
|
handle_pending_focused_surface_destroy;
|
||||||
|
wl_list_init(&input->pending_focused_surface_destroy.link);
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void relay_handle_text_input(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
text_input_new);
|
||||||
|
struct wlr_text_input_v3 *wlr_text_input = data;
|
||||||
|
if (seat != wlr_text_input->seat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwl_text_input_create(relay, wlr_text_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static LayerSurface* layer_surface_from_wlr_layer_surface_v1(
|
||||||
|
struct wlr_layer_surface_v1* layer_surface) {
|
||||||
|
return layer_surface->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void get_parent_and_output_box(struct wlr_surface *focused_surface,
|
||||||
|
struct wlr_box *parent, struct wlr_box *output_box) {
|
||||||
|
struct wlr_output *output;
|
||||||
|
struct wlr_box output_box_tmp;
|
||||||
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
|
|
||||||
|
if ((layer_surface=wlr_layer_surface_v1_try_from_wlr_surface(focused_surface))) {
|
||||||
|
LayerSurface* layer =
|
||||||
|
layer_surface_from_wlr_layer_surface_v1(layer_surface);
|
||||||
|
output = layer->layer_surface->output;
|
||||||
|
wlr_output_layout_get_box(output_layout, output,&output_box_tmp);
|
||||||
|
*parent = layer->geom;
|
||||||
|
parent->x += output_box_tmp.x;
|
||||||
|
parent->y += output_box_tmp.y;
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box layersurface output_box_tmp->x %d y %d",output_box_tmp.x, output_box_tmp.y);
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box layersurface parent->x %d y %d",parent->x,parent->y);
|
||||||
|
} else {
|
||||||
|
//Client *client = client_from_wlr_surface(focused_surface);
|
||||||
|
Client *client = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
|
int type = toplevel_from_wlr_surface(focused_surface, &client, &l);
|
||||||
|
|
||||||
|
output = wlr_output_layout_output_at(output_layout,
|
||||||
|
client->geom.x, client->geom.y);
|
||||||
|
wlr_output_layout_get_box(output_layout, output,&output_box_tmp);
|
||||||
|
|
||||||
|
parent->x = client->geom.x + client->bw;
|
||||||
|
parent->y = client->geom.y + client->bw;
|
||||||
|
parent->width = client->geom.width;
|
||||||
|
parent->height = client->geom.height;
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box client output_box_tmp->x %d y %d",output_box_tmp.x, output_box_tmp.y);
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box client client->geom.x %d y %d",client->geom.x,client->geom.y);
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box client client->bw %d",client->bw);
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box client parent->x %d y %d",parent->x,parent->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*output_box = output_box_tmp;
|
||||||
|
memcpy(output_box,&output_box_tmp,sizeof(struct wlr_box));
|
||||||
|
wlr_log(WLR_INFO,"get_parent_and_output_box output_box x %d y %d width %d height %d",output_box->x,output_box->y,output_box->width,output_box->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void input_popup_update(struct dwl_input_popup *popup) {
|
||||||
|
struct wlr_surface* focused_surface;
|
||||||
|
struct wlr_box output_box, parent, cursor;
|
||||||
|
int x1, x2, y1, y2, x, y, available_right, available_left, available_down,
|
||||||
|
available_up, popup_width, popup_height;
|
||||||
|
bool cursor_rect, x1_in_bounds, y1_in_bounds, x2_in_bounds, y2_in_bounds;
|
||||||
|
|
||||||
|
struct dwl_text_input *text_input =
|
||||||
|
relay_get_focused_text_input(popup->relay);
|
||||||
|
if (!text_input|| !text_input->input->focused_surface) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/743da5c0ae723098fe772aadb93810f60e700ab9
|
||||||
|
|
||||||
|
if (!popup->popup_surface->surface->mapped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor_rect = text_input->input->current.features
|
||||||
|
& WLR_TEXT_INPUT_V3_FEATURE_CURSOR_RECTANGLE;
|
||||||
|
|
||||||
|
focused_surface = text_input->input->focused_surface;
|
||||||
|
cursor = text_input->input->current.cursor_rectangle;
|
||||||
|
|
||||||
|
get_parent_and_output_box(focused_surface, &parent, &output_box);
|
||||||
|
|
||||||
|
popup_width = popup->popup_surface->surface->current.width;
|
||||||
|
popup_height = popup->popup_surface->surface->current.height;
|
||||||
|
|
||||||
|
if (!cursor_rect) {
|
||||||
|
cursor.x = 0;
|
||||||
|
cursor.y = 0;
|
||||||
|
cursor.width = parent.width;
|
||||||
|
cursor.height = parent.height;
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update !cursor_rect");
|
||||||
|
|
||||||
|
popup->x=parent.x;
|
||||||
|
popup->y=parent.y;
|
||||||
|
popup->visible=true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update cursor x %d y %d width %d height %d",cursor.x,cursor.y,cursor.width,cursor.height);
|
||||||
|
|
||||||
|
x1 = parent.x + cursor.x;
|
||||||
|
x2 = parent.x + cursor.x + cursor.width;
|
||||||
|
y1 = parent.y + cursor.y;
|
||||||
|
y2 = parent.y + cursor.y + cursor.height;
|
||||||
|
x = x1;
|
||||||
|
y = y2;
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update x1 %d x2 %d y1 %d y2 %d; x %d y %d",x1,x2,y1,y2,x,y);
|
||||||
|
available_right = output_box.x + output_box.width - x1;
|
||||||
|
available_left = x2 - output_box.x;
|
||||||
|
if (available_right < popup_width && available_left > available_right) {
|
||||||
|
x = x2 - popup_width;
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update available_left %d popup_width %d available_right %d; x %d",available_left,popup_width,available_right,x);
|
||||||
|
}
|
||||||
|
|
||||||
|
available_down = output_box.y + output_box.height - y2;
|
||||||
|
available_up = y1 - output_box.y;
|
||||||
|
if (available_down < popup_height && available_up > available_down) {
|
||||||
|
y = y1 - popup_height;
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update available up %d popup_height %d available_down %d; y %d",available_up,popup_height,available_down,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
popup->x = x;
|
||||||
|
popup->y = y;
|
||||||
|
|
||||||
|
// Hide popup if cursor position is completely out of bounds
|
||||||
|
x1_in_bounds = (cursor.x >= 0 && cursor.x < parent.width);
|
||||||
|
y1_in_bounds = (cursor.y >= 0 && cursor.y < parent.height);
|
||||||
|
x2_in_bounds = (cursor.x + cursor.width >= 0
|
||||||
|
&& cursor.x + cursor.width < parent.width);
|
||||||
|
y2_in_bounds = (cursor.y + cursor.height >= 0
|
||||||
|
&& cursor.y + cursor.height < parent.height);
|
||||||
|
popup->visible =
|
||||||
|
(x1_in_bounds && y1_in_bounds) || (x2_in_bounds && y2_in_bounds);
|
||||||
|
|
||||||
|
struct wlr_box box = {
|
||||||
|
.x = x1 - x,
|
||||||
|
.y = y1 - y,
|
||||||
|
.width = cursor.width,
|
||||||
|
.height = cursor.height,
|
||||||
|
};
|
||||||
|
wlr_input_popup_surface_v2_send_text_input_rectangle(
|
||||||
|
popup->popup_surface, &box);
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update send_text_input_rect box.x %d box.y %d",box.x,box.y);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"input_popup_update x %d y %d visible %s",popup->x,popup->y,popup->visible?"true":"false");
|
||||||
|
wlr_scene_node_set_position(&popup->scene->node, popup->x, popup->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_popup_map(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_input_popup *popup =
|
||||||
|
wl_container_of(listener, popup, popup_map);
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO, "IM_popup_map");
|
||||||
|
|
||||||
|
//popup->scene = &wlr_scene_tree_create(layers[LyrIMPopup])->node;
|
||||||
|
popup->scene = wlr_scene_tree_create(layers[LyrIMPopup]);
|
||||||
|
popup->scene_surface = wlr_scene_subsurface_tree_create(popup->scene,popup->popup_surface->surface);
|
||||||
|
//popup->scene_surface = &wlr_scene_subsurface_tree_create(popup->scene->parent,popup->popup_surface->surface)->node;
|
||||||
|
//popup->scene_surface->data = popup;
|
||||||
|
popup->scene_surface->node.data = popup;
|
||||||
|
|
||||||
|
input_popup_update(popup);
|
||||||
|
|
||||||
|
//wlr_scene_node_set_position(popup->scene, popup->x, popup->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_popup_unmap(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_input_popup *popup =
|
||||||
|
wl_container_of(listener, popup, popup_unmap);
|
||||||
|
//input_popup_update(popup);
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"im_popup_unmap");
|
||||||
|
wlr_scene_node_destroy(&popup->scene->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_im_popup_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_input_method_relay *relay;
|
||||||
|
struct dwl_input_popup *popup =
|
||||||
|
wl_container_of(listener, popup, popup_destroy);
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"im_popup_destroy");
|
||||||
|
|
||||||
|
wl_list_remove(&popup->popup_destroy.link);
|
||||||
|
wl_list_remove(&popup->popup_unmap.link);
|
||||||
|
wl_list_remove(&popup->popup_map.link);
|
||||||
|
|
||||||
|
relay=popup->relay;
|
||||||
|
free(popup->relay->popup);
|
||||||
|
relay->popup=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_im_new_popup_surface(struct wl_listener *listener, void *data) {
|
||||||
|
struct dwl_text_input* text_input;
|
||||||
|
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
input_method_new_popup_surface);
|
||||||
|
struct dwl_input_popup *popup = calloc(1, sizeof(*popup));
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO, "IM_new_popup_surface");
|
||||||
|
relay->popup = popup;
|
||||||
|
|
||||||
|
popup->relay = relay;
|
||||||
|
popup->popup_surface = data;
|
||||||
|
popup->popup_surface->data = popup;
|
||||||
|
|
||||||
|
|
||||||
|
wl_signal_add(&popup->popup_surface->surface->events.map, &popup->popup_map);
|
||||||
|
popup->popup_map.notify = handle_im_popup_map;
|
||||||
|
|
||||||
|
wl_signal_add(&popup->popup_surface->surface->events.unmap, &popup->popup_unmap);
|
||||||
|
popup->popup_unmap.notify = handle_im_popup_unmap;
|
||||||
|
|
||||||
|
wl_signal_add(
|
||||||
|
&popup->popup_surface->events.destroy, &popup->popup_destroy);
|
||||||
|
popup->popup_destroy.notify = handle_im_popup_destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void relay_handle_input_method(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct dwl_text_input *text_input;
|
||||||
|
|
||||||
|
struct dwl_input_method_relay *relay = wl_container_of(listener, relay,
|
||||||
|
input_method_new);
|
||||||
|
|
||||||
|
struct wlr_input_method_v2 *input_method = data;
|
||||||
|
if (seat != input_method->seat) {
|
||||||
|
wlr_log(WLR_INFO,"input_method_new Seat does not match");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relay->input_method != NULL) {
|
||||||
|
wlr_log(WLR_INFO, "input_method_new Attempted to connect second input method to a seat");
|
||||||
|
wlr_input_method_v2_send_unavailable(input_method);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_log(WLR_INFO,"input_method_new");
|
||||||
|
|
||||||
|
relay->input_method = input_method;
|
||||||
|
wl_signal_add(&relay->input_method->events.commit,
|
||||||
|
&relay->input_method_commit);
|
||||||
|
relay->input_method_commit.notify = handle_im_commit;
|
||||||
|
wl_signal_add(&relay->input_method->events.new_popup_surface,
|
||||||
|
&relay->input_method_new_popup_surface);
|
||||||
|
relay->input_method_new_popup_surface.notify = handle_im_new_popup_surface;
|
||||||
|
wl_signal_add(&relay->input_method->events.grab_keyboard,
|
||||||
|
&relay->input_method_grab_keyboard);
|
||||||
|
relay->input_method_grab_keyboard.notify = handle_im_grab_keyboard;
|
||||||
|
wl_signal_add(&relay->input_method->events.destroy,
|
||||||
|
&relay->input_method_destroy);
|
||||||
|
relay->input_method_destroy.notify = handle_im_destroy;
|
||||||
|
|
||||||
|
wlr_input_method_v2_send_activate(relay->input_method);
|
||||||
|
|
||||||
|
text_input = relay_get_focusable_text_input(relay);
|
||||||
|
if (text_input) {
|
||||||
|
wlr_text_input_v3_send_enter(text_input->input,
|
||||||
|
text_input->pending_focused_surface);
|
||||||
|
text_input_set_pending_focused_surface(text_input, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dwl_input_method_relay_init(struct dwl_input_method_relay *relay) {
|
||||||
|
wl_list_init(&relay->text_inputs);
|
||||||
|
|
||||||
|
relay->popup=NULL;
|
||||||
|
|
||||||
|
relay->text_input_new.notify = relay_handle_text_input;
|
||||||
|
wl_signal_add(&text_input_manager->events.text_input,
|
||||||
|
&relay->text_input_new);
|
||||||
|
|
||||||
|
relay->input_method_new.notify = relay_handle_input_method;
|
||||||
|
wl_signal_add(&input_method_manager->events.input_method,
|
||||||
|
&relay->input_method_new);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dwl_input_method_relay_set_focus(struct dwl_input_method_relay *relay,
|
||||||
|
struct wlr_surface *surface) {
|
||||||
|
struct dwl_text_input *text_input;
|
||||||
|
wl_list_for_each(text_input, &relay->text_inputs, link) {
|
||||||
|
if (text_input->pending_focused_surface) {
|
||||||
|
assert(text_input->input->focused_surface == NULL);
|
||||||
|
if (surface != text_input->pending_focused_surface) {
|
||||||
|
text_input_set_pending_focused_surface(text_input, NULL);
|
||||||
|
}
|
||||||
|
} else if (text_input->input->focused_surface) {
|
||||||
|
assert(text_input->pending_focused_surface == NULL);
|
||||||
|
if (surface != text_input->input->focused_surface) {
|
||||||
|
relay_disable_text_input(relay, text_input);
|
||||||
|
wlr_text_input_v3_send_leave(text_input->input);
|
||||||
|
wlr_log(WLR_INFO, "wlr_text_input_send_leave");
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_INFO, "IM relay set_focus already focused");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surface
|
||||||
|
&& wl_resource_get_client(text_input->input->resource)
|
||||||
|
== wl_resource_get_client(surface->resource)) {
|
||||||
|
if (relay->input_method) {
|
||||||
|
wlr_text_input_v3_send_enter(text_input->input, surface);
|
||||||
|
wlr_log(WLR_INFO, "wlr_text_input_send_enter");
|
||||||
|
if (relay->popup) input_popup_update(relay->popup);
|
||||||
|
} else {
|
||||||
|
text_input_set_pending_focused_surface(text_input, surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
39
LICENSE.dwm
Normal file
39
LICENSE.dwm
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
Portions of dwl based on dwm code are used under the following license:
|
||||||
|
|
||||||
|
MIT/X Consortium License
|
||||||
|
|
||||||
|
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
|
||||||
|
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
|
||||||
|
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
|
||||||
|
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
|
||||||
|
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
|
||||||
|
© 2007-2009 Christof Musik <christof at sendfax dot de>
|
||||||
|
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
|
||||||
|
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
|
||||||
|
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
|
||||||
|
© 2008 Neale Pickett <neale dot woozle dot org>
|
||||||
|
© 2009 Mate Nagy <mnagy at port70 dot net>
|
||||||
|
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||||
|
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
|
||||||
|
© 2011 Christoph Lohmann <20h@r-36.net>
|
||||||
|
© 2015-2016 Quentin Rameau <quinq@fifth.space>
|
||||||
|
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
|
||||||
|
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
|
||||||
|
|
||||||
|
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 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.
|
||||||
19
LICENSE.sway
Normal file
19
LICENSE.sway
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2016-2017 Drew DeVault
|
||||||
|
|
||||||
|
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 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.
|
||||||
127
LICENSE.tinywl
Normal file
127
LICENSE.tinywl
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
dwl is originally based on TinyWL, which is used under the following license:
|
||||||
|
|
||||||
|
This work is licensed under CC0, which effectively puts it in the public domain.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Creative Commons Legal Code
|
||||||
|
|
||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||||
|
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||||
|
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||||
|
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||||
|
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||||
|
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||||
|
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||||
|
HEREUNDER.
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||||
|
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for
|
||||||
|
the purpose of contributing to a commons of creative, cultural and
|
||||||
|
scientific works ("Commons") that the public can reliably and without fear
|
||||||
|
of later claims of infringement build upon, modify, incorporate in other
|
||||||
|
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||||
|
and for any purposes, including without limitation commercial purposes.
|
||||||
|
These owners may contribute to the Commons to promote the ideal of a free
|
||||||
|
culture and the further production of creative, cultural and scientific
|
||||||
|
works, or to gain reputation or greater distribution for their Work in
|
||||||
|
part through the use and efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any
|
||||||
|
expectation of additional consideration or compensation, the person
|
||||||
|
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||||
|
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||||
|
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||||
|
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||||
|
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not
|
||||||
|
limited to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display,
|
||||||
|
communicate, and translate a Work;
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or
|
||||||
|
likeness depicted in a Work;
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||||
|
in a Work;
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation
|
||||||
|
thereof, including any amended or successor version of such
|
||||||
|
directive); and
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the
|
||||||
|
world based on applicable law or treaty, and any national
|
||||||
|
implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||||
|
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||||
|
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||||
|
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||||
|
of action, whether now known or unknown (including existing as well as
|
||||||
|
future claims and causes of action), in the Work (i) in all territories
|
||||||
|
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||||
|
treaty (including future time extensions), (iii) in any current or future
|
||||||
|
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||||
|
including without limitation commercial, advertising or promotional
|
||||||
|
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||||
|
member of the public at large and to the detriment of Affirmer's heirs and
|
||||||
|
successors, fully intending that such Waiver shall not be subject to
|
||||||
|
revocation, rescission, cancellation, termination, or any other legal or
|
||||||
|
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||||
|
as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||||
|
be judged legally invalid or ineffective under applicable law, then the
|
||||||
|
Waiver shall be preserved to the maximum extent permitted taking into
|
||||||
|
account Affirmer's express Statement of Purpose. In addition, to the
|
||||||
|
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||||
|
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||||
|
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||||
|
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||||
|
maximum duration provided by applicable law or treaty (including future
|
||||||
|
time extensions), (iii) in any current or future medium and for any number
|
||||||
|
of copies, and (iv) for any purpose whatsoever, including without
|
||||||
|
limitation commercial, advertising or promotional purposes (the
|
||||||
|
"License"). The License shall be deemed effective as of the date CC0 was
|
||||||
|
applied by Affirmer to the Work. Should any part of the License for any
|
||||||
|
reason be judged legally invalid or ineffective under applicable law, such
|
||||||
|
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||||
|
of the License, and in such case Affirmer hereby affirms that he or she
|
||||||
|
will not (i) exercise any of his or her remaining Copyright and Related
|
||||||
|
Rights in the Work or (ii) assert any associated claims and causes of
|
||||||
|
action with respect to the Work, in either case contrary to Affirmer's
|
||||||
|
express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or
|
||||||
|
warranties of any kind concerning the Work, express, implied,
|
||||||
|
statutory or otherwise, including without limitation warranties of
|
||||||
|
title, merchantability, fitness for a particular purpose, non
|
||||||
|
infringement, or the absence of latent or other defects, accuracy, or
|
||||||
|
the present or absence of errors, whether or not discoverable, all to
|
||||||
|
the greatest extent permissible under applicable law.
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without
|
||||||
|
limitation any person's Copyright and Related Rights in the Work.
|
||||||
|
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||||
|
consents, permissions or other rights required for any use of the
|
||||||
|
Work.
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to
|
||||||
|
this CC0 or use of the Work.
|
||||||
692
LICENSE_1
Normal file
692
LICENSE_1
Normal file
|
|
@ -0,0 +1,692 @@
|
||||||
|
dwl - dwm for Wayland
|
||||||
|
|
||||||
|
Copyright © 2020 dwl team
|
||||||
|
|
||||||
|
See also the files LICENSE.tinywl, LICENSE.dwm and LICENSE.sway.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||||
65
README.md
65
README.md
|
|
@ -1,2 +1,63 @@
|
||||||
# plumewm
|
|
||||||
A streamlined but feature-rich wayland window tiling manager
|
https://github.com/user-attachments/assets/84eb21fd-1782-4edc-b504-50de35201abe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# feature
|
||||||
|
- dwl ipc support
|
||||||
|
- maxmize fullscreen
|
||||||
|
- swap window by direction
|
||||||
|
- swith to next not empty-workspace/workspace
|
||||||
|
- move window to next not empty-workspace/workspace
|
||||||
|
- swith focus by direction
|
||||||
|
- wheel/button + mod key bind
|
||||||
|
- hycov like overview
|
||||||
|
- numlock state pre-set in config
|
||||||
|
- portal fix for obs(use hyprland-portal)
|
||||||
|
- master layout support new_on_top
|
||||||
|
- foreign-toplevel support(dunst,waybar wlr taskbar)
|
||||||
|
- acitve on focus/urgent support
|
||||||
|
- hide empty button in waybar
|
||||||
|
- support minimize window by click waybar
|
||||||
|
- support minimize window by keyboard
|
||||||
|
- sway scratchpad support
|
||||||
|
- window pin mode support
|
||||||
|
- text-input-v2
|
||||||
|
- window move/open animaition
|
||||||
|
|
||||||
|
|
||||||
|
# install
|
||||||
|
# wlroots(0.17)
|
||||||
|
```
|
||||||
|
git clone -b 0.17.4 https://gitlab.freedesktop.org/wlroots/wlroots.git
|
||||||
|
cd wlroots
|
||||||
|
meson build -Dprefix=/usr
|
||||||
|
sudo ninja -C build install
|
||||||
|
|
||||||
|
git clone https://github.com/DreamMaoMao/mydwl.git
|
||||||
|
cd mydwl
|
||||||
|
meson build -Dprefix=/usr
|
||||||
|
sudo ninja -C build install
|
||||||
|
|
||||||
|
sed -i s#/home/user#$HOME#g dwl.desktop
|
||||||
|
sudo cp dwl.desktop /usr/share/wayland-sessions/
|
||||||
|
```
|
||||||
|
# dependcy
|
||||||
|
|
||||||
|
## tools
|
||||||
|
```
|
||||||
|
yay -S wofi foot
|
||||||
|
|
||||||
|
```
|
||||||
|
# waybar (must use this waybar)
|
||||||
|
```
|
||||||
|
git clone https://gitee.com/DreamMaoMao/Waybar.git
|
||||||
|
cd mywaybar
|
||||||
|
meson build -Dprefix=/usr
|
||||||
|
sudo ninja -C build install
|
||||||
|
```
|
||||||
|
|
||||||
|
# thanks for some refer repo
|
||||||
|
https://github.com/dqrk0jeste/owl - for window animation implementation code
|
||||||
|
https://github.com/djpohly/dwl - for base dwl code
|
||||||
|
|
||||||
|
|
|
||||||
15
autostart.sh
Executable file
15
autostart.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
set +e
|
||||||
|
|
||||||
|
systemctl --user unmask xdg-desktop-portal-hyprland
|
||||||
|
systemctl --user mask xdg-desktop-portal-gnome
|
||||||
|
|
||||||
|
dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
|
||||||
|
|
||||||
|
/usr/lib/xdg-desktop-portal-hyprland &
|
||||||
|
|
||||||
|
wl-clip-persist --clipboard regular &
|
||||||
|
wl-paste --type text --watch cliphist store &
|
||||||
|
|
||||||
|
|
||||||
408
client.h
Normal file
408
client.h
Normal file
|
|
@ -0,0 +1,408 @@
|
||||||
|
/*
|
||||||
|
* Attempt to consolidate unavoidable suck into one file, away from dwl.c. This
|
||||||
|
* file is not meant to be pretty. We use a .h file with static inline
|
||||||
|
* functions instead of a separate .c module, or function pointers like sway, so
|
||||||
|
* that they will simply compile out if the chosen #defines leave them unused.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Leave these functions first; they're used in the others */
|
||||||
|
static inline int
|
||||||
|
client_is_x11(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
return c->type == X11;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct wlr_surface *
|
||||||
|
client_surface(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return c->surface.xwayland->surface;
|
||||||
|
#endif
|
||||||
|
return c->surface.xdg->surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
|
||||||
|
{
|
||||||
|
struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface;
|
||||||
|
struct wlr_surface *root_surface;
|
||||||
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
|
Client *c = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
|
int type = -1;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
struct wlr_xwayland_surface *xsurface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return -1;
|
||||||
|
root_surface = wlr_surface_get_root_surface(s);
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) {
|
||||||
|
c = xsurface->data;
|
||||||
|
type = c->type;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((layer_surface = wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) {
|
||||||
|
l = layer_surface->data;
|
||||||
|
type = LayerShell;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface);
|
||||||
|
while (xdg_surface) {
|
||||||
|
tmp_xdg_surface = NULL;
|
||||||
|
switch (xdg_surface->role) {
|
||||||
|
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||||
|
if (!xdg_surface->popup || !xdg_surface->popup->parent)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
tmp_xdg_surface = wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent);
|
||||||
|
|
||||||
|
if (!tmp_xdg_surface)
|
||||||
|
return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
|
||||||
|
|
||||||
|
xdg_surface = tmp_xdg_surface;
|
||||||
|
break;
|
||||||
|
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||||
|
c = xdg_surface->data;
|
||||||
|
type = c->type;
|
||||||
|
goto end;
|
||||||
|
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (pl)
|
||||||
|
*pl = l;
|
||||||
|
if (pc)
|
||||||
|
*pc = c;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The others */
|
||||||
|
static inline void
|
||||||
|
client_activate_surface(struct wlr_surface *s, int activated)
|
||||||
|
{
|
||||||
|
struct wlr_xdg_toplevel *toplevel;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
struct wlr_xwayland_surface *xsurface;
|
||||||
|
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) {
|
||||||
|
wlr_xwayland_surface_activate(xsurface, activated);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s)))
|
||||||
|
wlr_xdg_toplevel_set_activated(toplevel, activated);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
client_set_bounds(Client *c, int32_t width, int32_t height)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >=
|
||||||
|
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0
|
||||||
|
&& (c->bounds.width != width || c->bounds.height != height)) {
|
||||||
|
c->bounds.width = width;
|
||||||
|
c->bounds.height = height;
|
||||||
|
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
client_get_appid(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return c->surface.xwayland->class;
|
||||||
|
#endif
|
||||||
|
return c->surface.xdg->toplevel->app_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_get_clip(Client *c, struct wlr_box *clip)
|
||||||
|
{
|
||||||
|
struct wlr_box xdg_geom = {0};
|
||||||
|
*clip = (struct wlr_box){
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = c->geom.width - c->bw,
|
||||||
|
.height = c->geom.height - c->bw,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom);
|
||||||
|
clip->x = xdg_geom.x;
|
||||||
|
clip->y = xdg_geom.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_get_geometry(Client *c, struct wlr_box *geom)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
geom->x = c->surface.xwayland->x;
|
||||||
|
geom->y = c->surface.xwayland->y;
|
||||||
|
geom->width = c->surface.xwayland->width;
|
||||||
|
geom->height = c->surface.xwayland->height;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Client *
|
||||||
|
client_get_parent(Client *c)
|
||||||
|
{
|
||||||
|
Client *p = NULL;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
if (c->surface.xwayland->parent)
|
||||||
|
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (c->surface.xdg->toplevel->parent)
|
||||||
|
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_has_children(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return !wl_list_empty(&c->surface.xwayland->children);
|
||||||
|
#endif
|
||||||
|
/* surface.xdg->link is never empty because it always contains at least the
|
||||||
|
* surface itself. */
|
||||||
|
return wl_list_length(&c->surface.xdg->link) > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char *
|
||||||
|
client_get_title(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return c->surface.xwayland->title;
|
||||||
|
#endif
|
||||||
|
return c->surface.xdg->toplevel->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_is_float_type(Client *c)
|
||||||
|
{
|
||||||
|
struct wlr_xdg_toplevel *toplevel;
|
||||||
|
struct wlr_xdg_toplevel_state state;
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
struct wlr_xwayland_surface *surface = c->surface.xwayland;
|
||||||
|
xcb_size_hints_t *size_hints = surface->size_hints;
|
||||||
|
size_t i;
|
||||||
|
if (surface->modal)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (i = 0; i < surface->window_type_len; i++)
|
||||||
|
if (surface->window_type[i] == netatom[NetWMWindowTypeDialog]
|
||||||
|
|| surface->window_type[i] == netatom[NetWMWindowTypeSplash]
|
||||||
|
|| surface->window_type[i] == netatom[NetWMWindowTypeToolbar]
|
||||||
|
|| surface->window_type[i] == netatom[NetWMWindowTypeUtility])
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return size_hints && size_hints->min_width > 0 && size_hints->min_height > 0
|
||||||
|
&& (size_hints->max_width == size_hints->min_width
|
||||||
|
|| size_hints->max_height == size_hints->min_height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
toplevel = c->surface.xdg->toplevel;
|
||||||
|
state = toplevel->current;
|
||||||
|
return toplevel->parent || (state.min_width != 0 && state.min_height != 0
|
||||||
|
&& (state.min_width == state.max_width
|
||||||
|
|| state.min_height == state.max_height));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_is_rendered_on_mon(Client *c, Monitor *m)
|
||||||
|
{
|
||||||
|
/* This is needed for when you don't want to check formal assignment,
|
||||||
|
* but rather actual displaying of the pixels.
|
||||||
|
* Usually VISIBLEON suffices and is also faster. */
|
||||||
|
struct wlr_surface_output *s;
|
||||||
|
int unused_lx, unused_ly;
|
||||||
|
if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly))
|
||||||
|
return 0;
|
||||||
|
wl_list_for_each(s, &client_surface(c)->current_outputs, link)
|
||||||
|
if (s->output == m->wlr_output)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_is_stopped(Client *c)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
siginfo_t in = {0};
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL);
|
||||||
|
if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) {
|
||||||
|
/* This process is not our child process, while is very unluckely that
|
||||||
|
* it is stopped, in order to do not skip frames assume that it is. */
|
||||||
|
if (errno == ECHILD)
|
||||||
|
return 1;
|
||||||
|
} else if (in.si_pid) {
|
||||||
|
if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED)
|
||||||
|
return 1;
|
||||||
|
if (in.si_code == CLD_CONTINUED)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_is_unmanaged(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return c->surface.xwayland->override_redirect;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb)
|
||||||
|
{
|
||||||
|
if (kb)
|
||||||
|
wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes,
|
||||||
|
kb->num_keycodes, &kb->modifiers);
|
||||||
|
else
|
||||||
|
wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_restack_surface(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
wlr_xwayland_surface_restack(c->surface.xwayland, NULL,
|
||||||
|
XCB_STACK_MODE_ABOVE);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_send_close(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
wlr_xwayland_surface_close(c->surface.xwayland);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_set_border_color(Client *c, const float color[static 4])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
wlr_scene_rect_set_color(c->border[i], color);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_set_fullscreen(Client *c, int fullscreen)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
client_set_size(Client *c, uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c)) {
|
||||||
|
wlr_xwayland_surface_configure(c->surface.xwayland,
|
||||||
|
c->geom.x, c->geom.y, width, height);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((int32_t)width == c->surface.xdg->toplevel->current.width
|
||||||
|
&& (int32_t)height == c->surface.xdg->toplevel->current.height)
|
||||||
|
return 0;
|
||||||
|
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width, (int32_t)height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_set_tiled(Client *c, uint32_t edges)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
if (wl_resource_get_version(c->surface.xdg->toplevel->resource)
|
||||||
|
>= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
||||||
|
wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
|
||||||
|
} else {
|
||||||
|
wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel, edges != WLR_EDGE_NONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
client_set_suspended(Client *c, int suspended)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_wants_focus(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
return client_is_unmanaged(c)
|
||||||
|
&& wlr_xwayland_or_surface_wants_focus(c->surface.xwayland)
|
||||||
|
&& wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_wants_fullscreen(Client *c)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return c->surface.xwayland->fullscreen;
|
||||||
|
#endif
|
||||||
|
return c->surface.xdg->toplevel->requested.fullscreen;
|
||||||
|
}
|
||||||
265
config.h
Normal file
265
config.h
Normal file
|
|
@ -0,0 +1,265 @@
|
||||||
|
/* speedie's dwl config */
|
||||||
|
|
||||||
|
#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
|
||||||
|
((hex >> 16) & 0xFF) / 255.0f, \
|
||||||
|
((hex >> 8) & 0xFF) / 255.0f, \
|
||||||
|
(hex & 0xFF) / 255.0f }
|
||||||
|
|
||||||
|
/* animation */
|
||||||
|
static const bool animations = true; // Enable animations
|
||||||
|
static const float zoom_initial_ratio = 0.5; // Initial window ratio for animations
|
||||||
|
static const uint32_t animation_duration = 300; // Animation speed
|
||||||
|
// static const double animation_curve[4] = {0.05,0.9,0.1,1.05}; // Animation curve
|
||||||
|
static const double animation_curve[4] = {0.46,1.0,0.29,0.99}; // Animation curve
|
||||||
|
|
||||||
|
/* appearance */
|
||||||
|
static const unsigned int axis_bind_apply_timeout = 100; // Timeout for wheel binding actions
|
||||||
|
static const unsigned int focus_on_activate = 1; // Automatically focus on window activation request
|
||||||
|
static const unsigned int new_is_master = 1; // New windows are inserted at the head
|
||||||
|
/* logging */
|
||||||
|
static int log_level = WLR_ERROR;
|
||||||
|
static const unsigned int numlockon = 1; // Enable numlock
|
||||||
|
static const unsigned int hotarea_size = 10; // Hot area size, 10x10
|
||||||
|
static const unsigned int enable_hotarea = 1; // Enable mouse hot area
|
||||||
|
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||||
|
static int sloppyfocus = 1; /* Focus follows mouse */
|
||||||
|
static unsigned int gappih = 5; /* Horizontal inner gap between windows */
|
||||||
|
static unsigned int gappiv = 5; /* Vertical inner gap between windows */
|
||||||
|
static unsigned int gappoh = 10; /* Horizontal outer gap between windows and screen edge */
|
||||||
|
static unsigned int gappov = 10; /* Vertical outer gap between windows and screen edge */
|
||||||
|
static int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if the surface isn't visible */
|
||||||
|
static unsigned int borderpx = 5; /* Border pixel of windows */
|
||||||
|
static const float rootcolor[] = COLOR(0x323232ff);
|
||||||
|
static const float bordercolor[] = COLOR(0x444444ff);
|
||||||
|
static const float focuscolor[] = COLOR(0xad741fff);
|
||||||
|
static const float fakefullscreencolor[] = COLOR(0x89aa61ff);
|
||||||
|
static const float urgentcolor[] = COLOR(0xad401fff);
|
||||||
|
static const float scratchpadcolor[] = COLOR(0x516c93ff);
|
||||||
|
static const float globalcolor[] = COLOR(0xb153a7ff);
|
||||||
|
// static const char *cursor_theme = "Bibata-Modern-Ice";
|
||||||
|
|
||||||
|
static const int overviewgappi = 5; /* Gap between windows and edges in overview mode */
|
||||||
|
static const int overviewgappo = 30; /* Gap between windows in overview mode */
|
||||||
|
|
||||||
|
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||||
|
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
||||||
|
|
||||||
|
static int warpcursor = 1; /* Warp cursor to focused client */
|
||||||
|
|
||||||
|
/* Autostart */
|
||||||
|
static const char *const autostart[] = {
|
||||||
|
"/bin/sh",
|
||||||
|
"-c",
|
||||||
|
"$DWL/autostart.sh",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tagging
|
||||||
|
* expand the array to add more tags
|
||||||
|
*/
|
||||||
|
static const char *tags[] = {
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"8",
|
||||||
|
"9",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Rule rules[] = {
|
||||||
|
/* app_id title tags mask isfloating isfullscreen isnoclip isnoborder monitor width height */
|
||||||
|
/* examples:
|
||||||
|
{ "Gimp", NULL, 0, 1, -1,800,600 },
|
||||||
|
*/
|
||||||
|
{ "Google-chrome", NULL, 1 << 3, 0, 0, 0, 0,-1, 0,0},
|
||||||
|
{ NULL, "Image Viewer", 0, 1, 0, 0, 0,-1, 0,0},
|
||||||
|
{ NULL, "Image View", 0, 1, 0, 0, 0,-1, 0,0},
|
||||||
|
{ NULL, "File Selector", 0, 1, 0, 0, 0,-1, 1200,800},
|
||||||
|
{ NULL, "Open File", 0, 1, 0, 0, 0,-1, 1200,800},
|
||||||
|
{ "polkit-gnome-authentication-agent-1", NULL, 0, 1, 0, 1, 1,-1, 930,230},
|
||||||
|
{ "blueman-manager", NULL, 0, 1, 0, 0, 0,-1, 700,600},
|
||||||
|
{ "Gnome-system-monitor", NULL, 0, 0, 0, 0, 0,-1, 700,600},
|
||||||
|
{ "obs", NULL, 1<<5, 0, 0, 0, 0,-1, 700,600},
|
||||||
|
{ "flameshot", NULL, 0, 0, 1, 0, 0,-1, 0,0},
|
||||||
|
{ NULL, "rofi - Networks", 0, 1, 0, 1, 1,-1, 0,0},
|
||||||
|
{ "Rofi", NULL, 0, 1, 0, 1, 1,-1, 0,0},
|
||||||
|
{ "wofi", NULL, 0, 1, 0, 0, 1,-1, 0,0},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
static const Layout overviewlayout = { "", overview };
|
||||||
|
|
||||||
|
static const Layout layouts[] = { // At least two layouts, cannot delete less than two
|
||||||
|
/* symbol arrange function */
|
||||||
|
{ "", tile }, // Stack layout
|
||||||
|
{ "", grid }, // Grid layout
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* monitors */
|
||||||
|
static const MonitorRule monrules[] = {
|
||||||
|
/* name mfact nmaster scale layout rotate/reflect x y*/
|
||||||
|
/* example of a HiDPI laptop monitor:
|
||||||
|
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
|
||||||
|
*/
|
||||||
|
/* defaults */
|
||||||
|
// { "eDP-1", 0.5, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
|
||||||
|
{ "eDP-1", 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0,0},
|
||||||
|
{ "HDMI-A-1", 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 1920,0},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* keyboard */
|
||||||
|
static const struct xkb_rule_names xkb_rules = {
|
||||||
|
/* can specify fields: rules, model, layout, variant, options */
|
||||||
|
/* example:
|
||||||
|
.options = "ctrl:nocaps",
|
||||||
|
*/
|
||||||
|
.options = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int repeat_rate = 25;
|
||||||
|
static int repeat_delay = 600;
|
||||||
|
|
||||||
|
/* Trackpad */
|
||||||
|
static int tap_to_click = 1;
|
||||||
|
static int tap_and_drag = 1;
|
||||||
|
static int drag_lock = 1;
|
||||||
|
static int natural_scrolling = 0;
|
||||||
|
static int disable_while_typing = 1;
|
||||||
|
static int left_handed = 0;
|
||||||
|
static int middle_button_emulation = 0;
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_SCROLL_NO_SCROLL
|
||||||
|
LIBINPUT_CONFIG_SCROLL_2FG
|
||||||
|
LIBINPUT_CONFIG_SCROLL_EDGE
|
||||||
|
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_NONE
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
|
||||||
|
*/
|
||||||
|
static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
|
||||||
|
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||||
|
static const double accel_speed = 0.0;
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
|
||||||
|
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||||
|
|
||||||
|
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
||||||
|
#define MODKEY WLR_MODIFIER_ALT
|
||||||
|
|
||||||
|
#define TAGKEYS(KEY,SKEY,TAG) \
|
||||||
|
{ WLR_MODIFIER_CTRL, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
|
{ WLR_MODIFIER_ALT, KEY, tag, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
|
||||||
|
|
||||||
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
|
||||||
|
/* commands */
|
||||||
|
// static const char *termcmd[] = { "foot", NULL };
|
||||||
|
// static const char *menucmd[] = { "wofi --conf $DWL/wofi/config_menu", NULL };
|
||||||
|
|
||||||
|
static const Key keys[] = {
|
||||||
|
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XKB_KEY_space, spawn, SHCMD("wofi") },
|
||||||
|
{ MODKEY, XKB_KEY_Return, spawn, SHCMD("foot") },
|
||||||
|
|
||||||
|
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_Tab, focusstack, {.i = +1} },
|
||||||
|
|
||||||
|
{ WLR_MODIFIER_ALT, XKB_KEY_Left, focusdir, {.i = LEFT } }, /* alt left | Switch focus window within the current tag */
|
||||||
|
{ WLR_MODIFIER_ALT, XKB_KEY_Right, focusdir, {.i = RIGHT } }, /* alt right | Switch focus window within the current tag */
|
||||||
|
{ WLR_MODIFIER_ALT, XKB_KEY_Up, focusdir, {.i = UP } }, /* alt up | Switch focus window within the current tag */
|
||||||
|
{ WLR_MODIFIER_ALT, XKB_KEY_Down, focusdir, {.i = DOWN } },
|
||||||
|
|
||||||
|
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_e, incnmaster, {.i = +1} },
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_t, incnmaster, {.i = -1} },
|
||||||
|
{ WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, XKB_KEY_Left, setmfact, {.f = -0.01} },
|
||||||
|
{ WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, XKB_KEY_Right, setmfact, {.f = +0.01} },
|
||||||
|
{ MODKEY, XKB_KEY_s, zoom, {0} },
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_Up, exchange_client, {.i = UP } }, /* super shift up | 2D exchange window (tiling only) */
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_Down, exchange_client, {.i = DOWN } }, /* super shift down | 2D exchange window (tiling only) */
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_Left, exchange_client, {.i = LEFT} }, /* super shift left | 2D exchange window (tiling only) */
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_Right, exchange_client, {.i = RIGHT } }, /* super shift right | 2D exchange window (tiling only) */
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_g, toggleglobal, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_Tab, toggleoverview, {0} },
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_Left, viewtoleft, {0} },
|
||||||
|
{ WLR_MODIFIER_CTRL, XKB_KEY_Left, viewtoleft_have_client, {0} },
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_Right, viewtoright, {0} },
|
||||||
|
{ WLR_MODIFIER_CTRL, XKB_KEY_Right, viewtoright_have_client, {0} },
|
||||||
|
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_Left, tagtoleft, {0} }, /* ctrl alt left | Move current window to the left tag */
|
||||||
|
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_Right, tagtoright, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_q, killclient, {0} },
|
||||||
|
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_LOGO, XKB_KEY_g, setlayout, {.v = &layouts[1]} },
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_n, switch_layout, {0} },
|
||||||
|
{ WLR_MODIFIER_ALT, XKB_KEY_backslash, togglefloating, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_a, togglefakefullscreen, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_f, togglefullscreen, {0} },
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_i, minized, {0} }, // Minimize, move to scratchpad
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_SHIFT, XKB_KEY_I, restore_minized, {0} },
|
||||||
|
{ WLR_MODIFIER_ALT, XKB_KEY_z, toggle_scratchpad, {0} }, // Cycle through scratchpad
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_bracketleft, focusmon, {.i = WLR_DIRECTION_LEFT} }, // super + [
|
||||||
|
{ WLR_MODIFIER_LOGO, XKB_KEY_bracketright, focusmon, {.i = WLR_DIRECTION_RIGHT} }, // suepr + ]
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_CTRL, XKB_KEY_bracketleft, tagmon, {.i = WLR_DIRECTION_LEFT} },
|
||||||
|
{ WLR_MODIFIER_LOGO|WLR_MODIFIER_CTRL, XKB_KEY_bracketright, tagmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_X, incgaps, {.i = +1 } },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Z, incgaps, {.i = -1 } },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_R, togglegaps, {0} },
|
||||||
|
TAGKEYS( XKB_KEY_KP_1, XKB_KEY_exclam, 0),
|
||||||
|
TAGKEYS( XKB_KEY_KP_2, XKB_KEY_at, 1),
|
||||||
|
TAGKEYS( XKB_KEY_KP_3, XKB_KEY_numbersign, 2),
|
||||||
|
TAGKEYS( XKB_KEY_KP_4, XKB_KEY_dollar, 3),
|
||||||
|
TAGKEYS( XKB_KEY_KP_5, XKB_KEY_percent, 4),
|
||||||
|
TAGKEYS( XKB_KEY_KP_6, XKB_KEY_asciicircum, 5),
|
||||||
|
TAGKEYS( XKB_KEY_KP_7, XKB_KEY_ampersand, 6),
|
||||||
|
TAGKEYS( XKB_KEY_KP_8, XKB_KEY_asterisk, 7),
|
||||||
|
TAGKEYS( XKB_KEY_KP_9, XKB_KEY_parenleft, 8),
|
||||||
|
//{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
|
||||||
|
|
||||||
|
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
||||||
|
{ WLR_MODIFIER_LOGO,XKB_KEY_m, quit, {0} },
|
||||||
|
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
|
||||||
|
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
|
||||||
|
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Button buttons[] = {
|
||||||
|
{ WLR_MODIFIER_LOGO, BTN_LEFT, moveresize, {.ui = CurMove } },
|
||||||
|
{ 0, BTN_MIDDLE, togglefakefullscreen, {0} }, // Middle button triggers fake fullscreen
|
||||||
|
{ WLR_MODIFIER_LOGO, BTN_RIGHT, moveresize, {.ui = CurResize } },
|
||||||
|
{ WLR_MODIFIER_ALT|WLR_MODIFIER_CTRL, BTN_LEFT, spawn, SHCMD("bash ~/tool/shotTranslate.sh shot")},
|
||||||
|
{ 0, BTN_LEFT, toggleoverview, {0} },
|
||||||
|
{ 0, BTN_RIGHT, killclient, {0} },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Axis axes[] = {
|
||||||
|
{ WLR_MODIFIER_LOGO, AxisUp, viewtoleft_have_client, {0} }, // Middle button + super to switch workspace forward
|
||||||
|
{ WLR_MODIFIER_LOGO, AxisDown, viewtoright_have_client, {0} }, // Middle button + super to switch workspace backward
|
||||||
|
};
|
||||||
367
cursor-shape-v1-protocol.h
Normal file
367
cursor-shape-v1-protocol.h
Normal file
|
|
@ -0,0 +1,367 @@
|
||||||
|
/* Generated by wayland-scanner 1.22.0 */
|
||||||
|
|
||||||
|
#ifndef CURSOR_SHAPE_V1_SERVER_PROTOCOL_H
|
||||||
|
#define CURSOR_SHAPE_V1_SERVER_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-server.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wl_client;
|
||||||
|
struct wl_resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_cursor_shape_v1 The cursor_shape_v1 protocol
|
||||||
|
* @section page_ifaces_cursor_shape_v1 Interfaces
|
||||||
|
* - @subpage page_iface_wp_cursor_shape_manager_v1 - cursor shape manager
|
||||||
|
* - @subpage page_iface_wp_cursor_shape_device_v1 - cursor shape for a device
|
||||||
|
* @section page_copyright_cursor_shape_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright 2018 The Chromium Authors
|
||||||
|
* Copyright 2023 Simon Ser
|
||||||
|
*
|
||||||
|
* 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_pointer;
|
||||||
|
struct wp_cursor_shape_device_v1;
|
||||||
|
struct wp_cursor_shape_manager_v1;
|
||||||
|
struct zwp_tablet_tool_v2;
|
||||||
|
|
||||||
|
#ifndef WP_CURSOR_SHAPE_MANAGER_V1_INTERFACE
|
||||||
|
#define WP_CURSOR_SHAPE_MANAGER_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_wp_cursor_shape_manager_v1 wp_cursor_shape_manager_v1
|
||||||
|
* @section page_iface_wp_cursor_shape_manager_v1_desc Description
|
||||||
|
*
|
||||||
|
* This global offers an alternative, optional way to set cursor images. This
|
||||||
|
* new way uses enumerated cursors instead of a wl_surface like
|
||||||
|
* wl_pointer.set_cursor does.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is currently in the testing
|
||||||
|
* phase. Backward compatible changes may be added together with the
|
||||||
|
* corresponding interface version bump. Backward incompatible changes can
|
||||||
|
* only be done by creating a new major version of the extension.
|
||||||
|
* @section page_iface_wp_cursor_shape_manager_v1_api API
|
||||||
|
* See @ref iface_wp_cursor_shape_manager_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_wp_cursor_shape_manager_v1 The wp_cursor_shape_manager_v1 interface
|
||||||
|
*
|
||||||
|
* This global offers an alternative, optional way to set cursor images. This
|
||||||
|
* new way uses enumerated cursors instead of a wl_surface like
|
||||||
|
* wl_pointer.set_cursor does.
|
||||||
|
*
|
||||||
|
* Warning! The protocol described in this file is currently in the testing
|
||||||
|
* phase. Backward compatible changes may be added together with the
|
||||||
|
* corresponding interface version bump. Backward incompatible changes can
|
||||||
|
* only be done by creating a new major version of the extension.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface wp_cursor_shape_manager_v1_interface;
|
||||||
|
#endif
|
||||||
|
#ifndef WP_CURSOR_SHAPE_DEVICE_V1_INTERFACE
|
||||||
|
#define WP_CURSOR_SHAPE_DEVICE_V1_INTERFACE
|
||||||
|
/**
|
||||||
|
* @page page_iface_wp_cursor_shape_device_v1 wp_cursor_shape_device_v1
|
||||||
|
* @section page_iface_wp_cursor_shape_device_v1_desc Description
|
||||||
|
*
|
||||||
|
* This interface advertises the list of supported cursor shapes for a
|
||||||
|
* device, and allows clients to set the cursor shape.
|
||||||
|
* @section page_iface_wp_cursor_shape_device_v1_api API
|
||||||
|
* See @ref iface_wp_cursor_shape_device_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_wp_cursor_shape_device_v1 The wp_cursor_shape_device_v1 interface
|
||||||
|
*
|
||||||
|
* This interface advertises the list of supported cursor shapes for a
|
||||||
|
* device, and allows clients to set the cursor shape.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface wp_cursor_shape_device_v1_interface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_manager_v1
|
||||||
|
* @struct wp_cursor_shape_manager_v1_interface
|
||||||
|
*/
|
||||||
|
struct wp_cursor_shape_manager_v1_interface {
|
||||||
|
/**
|
||||||
|
* destroy the manager
|
||||||
|
*
|
||||||
|
* Destroy the cursor shape manager.
|
||||||
|
*/
|
||||||
|
void (*destroy)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource);
|
||||||
|
/**
|
||||||
|
* manage the cursor shape of a pointer device
|
||||||
|
*
|
||||||
|
* Obtain a wp_cursor_shape_device_v1 for a wl_pointer object.
|
||||||
|
*/
|
||||||
|
void (*get_pointer)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t cursor_shape_device,
|
||||||
|
struct wl_resource *pointer);
|
||||||
|
/**
|
||||||
|
* manage the cursor shape of a tablet tool device
|
||||||
|
*
|
||||||
|
* Obtain a wp_cursor_shape_device_v1 for a zwp_tablet_tool_v2
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
void (*get_tablet_tool_v2)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t cursor_shape_device,
|
||||||
|
struct wl_resource *tablet_tool);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_manager_v1
|
||||||
|
*/
|
||||||
|
#define WP_CURSOR_SHAPE_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_manager_v1
|
||||||
|
*/
|
||||||
|
#define WP_CURSOR_SHAPE_MANAGER_V1_GET_POINTER_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_manager_v1
|
||||||
|
*/
|
||||||
|
#define WP_CURSOR_SHAPE_MANAGER_V1_GET_TABLET_TOOL_V2_SINCE_VERSION 1
|
||||||
|
|
||||||
|
#ifndef WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ENUM
|
||||||
|
#define WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_device_v1
|
||||||
|
* cursor shapes
|
||||||
|
*
|
||||||
|
* This enum describes cursor shapes.
|
||||||
|
*
|
||||||
|
* The names are taken from the CSS W3C specification:
|
||||||
|
* https://w3c.github.io/csswg-drafts/css-ui/#cursor
|
||||||
|
*/
|
||||||
|
enum wp_cursor_shape_device_v1_shape {
|
||||||
|
/**
|
||||||
|
* default cursor
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT = 1,
|
||||||
|
/**
|
||||||
|
* a context menu is available for the object under the cursor
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CONTEXT_MENU = 2,
|
||||||
|
/**
|
||||||
|
* help is available for the object under the cursor
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP = 3,
|
||||||
|
/**
|
||||||
|
* pointer that indicates a link or another interactive element
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER = 4,
|
||||||
|
/**
|
||||||
|
* progress indicator
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS = 5,
|
||||||
|
/**
|
||||||
|
* program is busy, user should wait
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT = 6,
|
||||||
|
/**
|
||||||
|
* a cell or set of cells may be selected
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CELL = 7,
|
||||||
|
/**
|
||||||
|
* simple crosshair
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR = 8,
|
||||||
|
/**
|
||||||
|
* text may be selected
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT = 9,
|
||||||
|
/**
|
||||||
|
* vertical text may be selected
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_VERTICAL_TEXT = 10,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: alias of/shortcut to something is to be created
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALIAS = 11,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: something is to be copied
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COPY = 12,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: something is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE = 13,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: the dragged item cannot be dropped at the current cursor location
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP = 14,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: the requested action will not be carried out
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NOT_ALLOWED = 15,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: something can be grabbed
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB = 16,
|
||||||
|
/**
|
||||||
|
* drag-and-drop: something is being grabbed
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING = 17,
|
||||||
|
/**
|
||||||
|
* resizing: the east border is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_E_RESIZE = 18,
|
||||||
|
/**
|
||||||
|
* resizing: the north border is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_N_RESIZE = 19,
|
||||||
|
/**
|
||||||
|
* resizing: the north-east corner is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NE_RESIZE = 20,
|
||||||
|
/**
|
||||||
|
* resizing: the north-west corner is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NW_RESIZE = 21,
|
||||||
|
/**
|
||||||
|
* resizing: the south border is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_S_RESIZE = 22,
|
||||||
|
/**
|
||||||
|
* resizing: the south-east corner is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SE_RESIZE = 23,
|
||||||
|
/**
|
||||||
|
* resizing: the south-west corner is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SW_RESIZE = 24,
|
||||||
|
/**
|
||||||
|
* resizing: the west border is to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_W_RESIZE = 25,
|
||||||
|
/**
|
||||||
|
* resizing: the east and west borders are to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE = 26,
|
||||||
|
/**
|
||||||
|
* resizing: the north and south borders are to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE = 27,
|
||||||
|
/**
|
||||||
|
* resizing: the north-east and south-west corners are to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE = 28,
|
||||||
|
/**
|
||||||
|
* resizing: the north-west and south-east corners are to be moved
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE = 29,
|
||||||
|
/**
|
||||||
|
* resizing: that the item/column can be resized horizontally
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COL_RESIZE = 30,
|
||||||
|
/**
|
||||||
|
* resizing: that the item/row can be resized vertically
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ROW_RESIZE = 31,
|
||||||
|
/**
|
||||||
|
* something can be scrolled in any direction
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ALL_SCROLL = 32,
|
||||||
|
/**
|
||||||
|
* something can be zoomed in
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_IN = 33,
|
||||||
|
/**
|
||||||
|
* something can be zoomed out
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ZOOM_OUT = 34,
|
||||||
|
};
|
||||||
|
#endif /* WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ENUM */
|
||||||
|
|
||||||
|
#ifndef WP_CURSOR_SHAPE_DEVICE_V1_ERROR_ENUM
|
||||||
|
#define WP_CURSOR_SHAPE_DEVICE_V1_ERROR_ENUM
|
||||||
|
enum wp_cursor_shape_device_v1_error {
|
||||||
|
/**
|
||||||
|
* the specified shape value is invalid
|
||||||
|
*/
|
||||||
|
WP_CURSOR_SHAPE_DEVICE_V1_ERROR_INVALID_SHAPE = 1,
|
||||||
|
};
|
||||||
|
#endif /* WP_CURSOR_SHAPE_DEVICE_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_device_v1
|
||||||
|
* @struct wp_cursor_shape_device_v1_interface
|
||||||
|
*/
|
||||||
|
struct wp_cursor_shape_device_v1_interface {
|
||||||
|
/**
|
||||||
|
* destroy the cursor shape device
|
||||||
|
*
|
||||||
|
* Destroy the cursor shape device.
|
||||||
|
*
|
||||||
|
* The device cursor shape remains unchanged.
|
||||||
|
*/
|
||||||
|
void (*destroy)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource);
|
||||||
|
/**
|
||||||
|
* set device cursor to the shape
|
||||||
|
*
|
||||||
|
* Sets the device cursor to the specified shape. The compositor
|
||||||
|
* will change the cursor image based on the specified shape.
|
||||||
|
*
|
||||||
|
* The cursor actually changes only if the input device focus is
|
||||||
|
* one of the requesting client's surfaces. If any, the previous
|
||||||
|
* cursor image (surface or shape) is replaced.
|
||||||
|
*
|
||||||
|
* The "shape" argument must be a valid enum entry, otherwise the
|
||||||
|
* invalid_shape protocol error is raised.
|
||||||
|
*
|
||||||
|
* This is similar to the wl_pointer.set_cursor and
|
||||||
|
* zwp_tablet_tool_v2.set_cursor requests, but this request accepts
|
||||||
|
* a shape instead of contents in the form of a surface. Clients
|
||||||
|
* can mix set_cursor and set_shape requests.
|
||||||
|
*
|
||||||
|
* The serial parameter must match the latest wl_pointer.enter or
|
||||||
|
* zwp_tablet_tool_v2.proximity_in serial number sent to the
|
||||||
|
* client. Otherwise the request will be ignored.
|
||||||
|
* @param serial serial number of the enter event
|
||||||
|
*/
|
||||||
|
void (*set_shape)(struct wl_client *client,
|
||||||
|
struct wl_resource *resource,
|
||||||
|
uint32_t serial,
|
||||||
|
uint32_t shape);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_device_v1
|
||||||
|
*/
|
||||||
|
#define WP_CURSOR_SHAPE_DEVICE_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_wp_cursor_shape_device_v1
|
||||||
|
*/
|
||||||
|
#define WP_CURSOR_SHAPE_DEVICE_V1_SET_SHAPE_SINCE_VERSION 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
151
dwl.1
Normal file
151
dwl.1
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
.Dd January 8, 2021
|
||||||
|
.Dt DWL 1
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm dwl
|
||||||
|
.Nd dwm for Wayland
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl v
|
||||||
|
.Op Fl s Ar startup command
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
.Nm
|
||||||
|
is a Wayland compositor based on wlroots.
|
||||||
|
It is intended to fill the same space in the Wayland world that
|
||||||
|
.Nm dwm
|
||||||
|
does for X11.
|
||||||
|
.Pp
|
||||||
|
When given the
|
||||||
|
.Fl v
|
||||||
|
option,
|
||||||
|
.Nm
|
||||||
|
writes its name and version to standard error and exits unsuccessfully.
|
||||||
|
.Pp
|
||||||
|
When given the
|
||||||
|
.Fl s
|
||||||
|
option,
|
||||||
|
.Nm
|
||||||
|
starts a shell process running
|
||||||
|
.Ar command
|
||||||
|
when starting.
|
||||||
|
When stopping, it sends
|
||||||
|
.Dv SIGTERM
|
||||||
|
to the child process and waits for it to exit.
|
||||||
|
.Pp
|
||||||
|
Users are encouraged to customize
|
||||||
|
.Nm
|
||||||
|
by editing the sources, in particular
|
||||||
|
.Pa config.h .
|
||||||
|
The default key bindings are as follows:
|
||||||
|
.Bl -tag -width 20n -offset indent -compact
|
||||||
|
.It Mod-[1-9]
|
||||||
|
Show only all windows with a tag.
|
||||||
|
.It Mod-Ctrl-[1-9]
|
||||||
|
Show all windows with a tag.
|
||||||
|
.It Mod-Shift-[1-9]
|
||||||
|
Move window to a single tag.
|
||||||
|
.It Mod-Ctrl-Shift-[1-9]
|
||||||
|
Toggle tag for window.
|
||||||
|
.It Mod-p
|
||||||
|
Spawn
|
||||||
|
.Nm bemenu-run .
|
||||||
|
.It Mod-Shift-Return
|
||||||
|
Spawn
|
||||||
|
.Nm foot .
|
||||||
|
.It Mod-[jk]
|
||||||
|
Move focus down/up the stack.
|
||||||
|
.It Mod-[id]
|
||||||
|
Increase/decrease number of windows in master area.
|
||||||
|
.It Mod-[hl]
|
||||||
|
Decrease/increase master area.
|
||||||
|
.It Mod-Return
|
||||||
|
Move window on top of stack or switch top of stack with second window.
|
||||||
|
.It Mod-Tab
|
||||||
|
Show only all windows with previous tag.
|
||||||
|
.It Mod-Shift-c
|
||||||
|
Close window.
|
||||||
|
.It Mod-t
|
||||||
|
Switch to tabbed layout.
|
||||||
|
.It Mod-f
|
||||||
|
Switch to floating layout.
|
||||||
|
.It Mod-m
|
||||||
|
Switch to monocle layout.
|
||||||
|
.It Mod-Space
|
||||||
|
Switch to previous layout.
|
||||||
|
.It Mod-Shift-Space
|
||||||
|
Toggle floating state of window.
|
||||||
|
.It Mod-e
|
||||||
|
Toggle fullscreen state of window.
|
||||||
|
.It Mod-0
|
||||||
|
Show all windows.
|
||||||
|
.It Mod-Shift-0
|
||||||
|
Set all tags for window.
|
||||||
|
.It Mod-,
|
||||||
|
Move focus to previous monitor.
|
||||||
|
.It Mod-.
|
||||||
|
Move focus to next monitor.
|
||||||
|
.It Mod-Shift-,
|
||||||
|
Move window to previous monitor.
|
||||||
|
.It Mod-Shift-.
|
||||||
|
Move window to next monitor.
|
||||||
|
.It Mod-Shift-q
|
||||||
|
Quit
|
||||||
|
.Nm .
|
||||||
|
.El
|
||||||
|
These might differ depending on your keyboard layout.
|
||||||
|
.Sh ENVIRONMENT
|
||||||
|
These environment variables are used by
|
||||||
|
.Nm :
|
||||||
|
.Bl -tag -width XDG_RUNTIME_DIR
|
||||||
|
.It Ev XDG_RUNTIME_DIR
|
||||||
|
A directory where temporary user files, such as the Wayland socket,
|
||||||
|
are stored.
|
||||||
|
.It Ev XDG_CONFIG_DIR
|
||||||
|
A directory containung configuration of various programs and
|
||||||
|
libraries, including libxkbcommon.
|
||||||
|
.It Ev DISPLAY , WAYLAND_DISPLAY , WAYLAND_SOCKET
|
||||||
|
Tell how to connect to an underlying X11 or Wayland server.
|
||||||
|
.It Ev WLR_*
|
||||||
|
Various variables specific to wlroots.
|
||||||
|
.It Ev XKB_* , XLOCALEDIR , XCOMPOSEFILE
|
||||||
|
Various variables specific to libxkbcommon.
|
||||||
|
.It Ev XCURSOR_PATH
|
||||||
|
List of directories to search for XCursor themes in.
|
||||||
|
.It Ev HOME
|
||||||
|
A directory where there are always dear files there for you.
|
||||||
|
Waiting for you to clean them up.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
These are set by
|
||||||
|
.Nm :
|
||||||
|
.Bl -tag -width WAYLAND_DISPLAY
|
||||||
|
.It Ev WAYLAND_DISPLAY
|
||||||
|
Tell how to connect to
|
||||||
|
.Nm .
|
||||||
|
.It Ev DISPLAY
|
||||||
|
If using
|
||||||
|
.Nm Xwayland ,
|
||||||
|
tell how to connect to the
|
||||||
|
.Nm Xwayland
|
||||||
|
server.
|
||||||
|
.El
|
||||||
|
.Sh EXAMPLES
|
||||||
|
Start
|
||||||
|
.Nm
|
||||||
|
with s6 in the background:
|
||||||
|
.Dl dwl -s 's6-svscan <&-'
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr foot 1 ,
|
||||||
|
.Xr bemenu 1 ,
|
||||||
|
.Xr dwm 1 ,
|
||||||
|
.Xr xkeyboard-config 7
|
||||||
|
.Sh CAVEATS
|
||||||
|
The child process's standard input is connected with a pipe to
|
||||||
|
.Nm .
|
||||||
|
If the child process neither reads from the pipe nor closes its
|
||||||
|
standard input,
|
||||||
|
.Nm
|
||||||
|
will freeze after a while due to it blocking when writing to the full
|
||||||
|
pipe buffer.
|
||||||
|
.Sh BUGS
|
||||||
|
All of them.
|
||||||
7
dwl.desktop
Normal file
7
dwl.desktop
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Name=Dwl
|
||||||
|
Comment=Dynamic window manager for wayland
|
||||||
|
Exec=env XDG_CURRENT_DESKTOP=sway DWL=/home/user/.config/dwl dwl
|
||||||
|
Icon=dwl
|
||||||
|
Type=Application
|
||||||
50
meson.build
Normal file
50
meson.build
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
project('dwl', ['c', 'cpp'],
|
||||||
|
version : '0.4'
|
||||||
|
)
|
||||||
|
|
||||||
|
subdir('protocols')
|
||||||
|
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
libm = cc.find_library('m')
|
||||||
|
xcb = dependency('xcb', required : get_option('xwayland'))
|
||||||
|
xlibs = dependency('xcb-icccm', required : get_option('xwayland'))
|
||||||
|
wayland_server_dep = dependency('wayland-server')
|
||||||
|
wlroots_dep = dependency('wlroots', version : ['>=0.17.0', '<0.18.0'])
|
||||||
|
xkbcommon_dep = dependency('xkbcommon')
|
||||||
|
libinput_dep = dependency('libinput')
|
||||||
|
libwayland_client_dep = dependency('wayland-client')
|
||||||
|
|
||||||
|
c_args = [
|
||||||
|
'-g',
|
||||||
|
'-Wno-unused-function',
|
||||||
|
'-DWLR_USE_UNSTABLE',
|
||||||
|
'-D_POSIX_C_SOURCE=200809L',
|
||||||
|
'-DVERSION="@0@"'.format(meson.project_version())
|
||||||
|
]
|
||||||
|
|
||||||
|
if xcb.found() and xlibs.found()
|
||||||
|
c_args += '-DXWAYLAND'
|
||||||
|
c_args += '-DIM'
|
||||||
|
endif
|
||||||
|
|
||||||
|
executable('dwl',
|
||||||
|
'dwl.c',
|
||||||
|
'util.c',
|
||||||
|
'wlr_foreign_toplevel_management_v1.c',
|
||||||
|
'wlr_foreign_toplevel_management_v1.h',
|
||||||
|
wayland_sources,
|
||||||
|
dependencies : [
|
||||||
|
libm,
|
||||||
|
xcb,
|
||||||
|
xlibs,
|
||||||
|
wayland_server_dep,
|
||||||
|
wlroots_dep,
|
||||||
|
xkbcommon_dep,
|
||||||
|
libinput_dep,
|
||||||
|
libwayland_client_dep,
|
||||||
|
],
|
||||||
|
install : true,
|
||||||
|
c_args : c_args
|
||||||
|
)
|
||||||
|
|
||||||
|
install_man('dwl.1')
|
||||||
1
meson_options.txt
Normal file
1
meson_options.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
option('xwayland', type : 'feature', value : 'enabled')
|
||||||
166
protocols/dwl-ipc-unstable-v2.xml
Normal file
166
protocols/dwl-ipc-unstable-v2.xml
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
<?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_ipc_unstable_v2">
|
||||||
|
<description summary="inter-proccess-communication about dwl's state">
|
||||||
|
This protocol allows clients to update and get updates from dwl.
|
||||||
|
|
||||||
|
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.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<interface name="zdwl_ipc_manager_v2" 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_ipc_output.
|
||||||
|
After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
|
||||||
|
The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="release" type="destructor">
|
||||||
|
<description summary="release dwl_ipc_manager">
|
||||||
|
Indicates that the client will not the dwl_ipc_manager object anymore.
|
||||||
|
Objects created through this instance are not affected.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_output">
|
||||||
|
<description summary="get a dwl_ipc_outout for a wl_output">
|
||||||
|
Get a dwl_ipc_outout for the specified wl_output.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/>
|
||||||
|
<arg name="output" type="object" interface="wl_output"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="tags">
|
||||||
|
<description summary="Announces tag amount">
|
||||||
|
This event is sent after binding.
|
||||||
|
A roundtrip after binding guarantees the client recieved all tags.
|
||||||
|
</description>
|
||||||
|
<arg name="amount" type="uint"/>
|
||||||
|
</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_ipc_output_v2" 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_ipc_output.frame 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_ipc_outout">
|
||||||
|
Indicates to that the client no longer needs this dwl_ipc_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="appid" since="1">
|
||||||
|
<description summary="Update the appid.">
|
||||||
|
Indicates the appid has changed.
|
||||||
|
</description>
|
||||||
|
<arg name="appid" type="string" summary="The new appid."/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="layout_symbol" since="1">
|
||||||
|
<description summary="Update the current layout symbol">
|
||||||
|
Indicates the layout has changed. Since layout symbols are dynamic.
|
||||||
|
As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying.
|
||||||
|
You can ignore the zdwl_ipc_output.layout event.
|
||||||
|
</description>
|
||||||
|
<arg name="layout" type="string" summary="The new layout"/>
|
||||||
|
</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_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>
|
||||||
|
|
||||||
|
<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_ipc_manager.layout"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
||||||
24
protocols/meson.build
Normal file
24
protocols/meson.build
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
wayland_scanner = find_program('wayland-scanner')
|
||||||
|
wayland_protos_dep = dependency('wayland-protocols')
|
||||||
|
wl_protocol_dir = wayland_protos_dep.get_pkgconfig_variable('pkgdatadir')
|
||||||
|
wayland_scanner_code = generator(
|
||||||
|
wayland_scanner,
|
||||||
|
output: '@BASENAME@-protocol.c',
|
||||||
|
arguments: ['private-code', '@INPUT@', '@OUTPUT@'])
|
||||||
|
wayland_scanner_client = generator(
|
||||||
|
wayland_scanner,
|
||||||
|
output: '@BASENAME@-protocol.h',
|
||||||
|
arguments: ['server-header', '@INPUT@', '@OUTPUT@'])
|
||||||
|
|
||||||
|
wayland_xmls = [
|
||||||
|
wl_protocol_dir + '/stable/xdg-shell/xdg-shell.xml',
|
||||||
|
'wlr-layer-shell-unstable-v1.xml',
|
||||||
|
'pointer-constraints-unstable-v1.xml',
|
||||||
|
'wlr-foreign-toplevel-management-unstable-v1.xml',
|
||||||
|
'dwl-ipc-unstable-v2.xml',
|
||||||
|
# 'cursor-shape-v1.xml'
|
||||||
|
]
|
||||||
|
wayland_sources = [
|
||||||
|
wayland_scanner_code.process(wayland_xmls),
|
||||||
|
wayland_scanner_client.process(wayland_xmls),
|
||||||
|
]
|
||||||
339
protocols/pointer-constraints-unstable-v1.xml
Executable file
339
protocols/pointer-constraints-unstable-v1.xml
Executable file
|
|
@ -0,0 +1,339 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="pointer_constraints_unstable_v1">
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2014 Jonas Ådahl
|
||||||
|
Copyright © 2015 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.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<description summary="protocol for constraining pointer motions">
|
||||||
|
This protocol specifies a set of interfaces used for adding constraints to
|
||||||
|
the motion of a pointer. Possible constraints include confining pointer
|
||||||
|
motions to a given region, or locking it to its current position.
|
||||||
|
|
||||||
|
In order to constrain the pointer, a client must first bind the global
|
||||||
|
interface "wp_pointer_constraints" which, if a compositor supports pointer
|
||||||
|
constraints, is exposed by the registry. Using the bound global object, the
|
||||||
|
client uses the request that corresponds to the type of constraint it wants
|
||||||
|
to make. See wp_pointer_constraints for more details.
|
||||||
|
|
||||||
|
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.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<interface name="zwp_pointer_constraints_v1" version="1">
|
||||||
|
<description summary="constrain the movement of a pointer">
|
||||||
|
The global interface exposing pointer constraining functionality. It
|
||||||
|
exposes two requests: lock_pointer for locking the pointer to its
|
||||||
|
position, and confine_pointer for locking the pointer to a region.
|
||||||
|
|
||||||
|
The lock_pointer and confine_pointer requests create the objects
|
||||||
|
wp_locked_pointer and wp_confined_pointer respectively, and the client can
|
||||||
|
use these objects to interact with the lock.
|
||||||
|
|
||||||
|
For any surface, only one lock or confinement may be active across all
|
||||||
|
wl_pointer objects of the same seat. If a lock or confinement is requested
|
||||||
|
when another lock or confinement is active or requested on the same surface
|
||||||
|
and with any of the wl_pointer objects of the same seat, an
|
||||||
|
'already_constrained' error will be raised.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<description summary="wp_pointer_constraints error values">
|
||||||
|
These errors can be emitted in response to wp_pointer_constraints
|
||||||
|
requests.
|
||||||
|
</description>
|
||||||
|
<entry name="already_constrained" value="1"
|
||||||
|
summary="pointer constraint already requested on that surface"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<enum name="lifetime">
|
||||||
|
<description summary="constraint lifetime">
|
||||||
|
These values represent different lifetime semantics. They are passed
|
||||||
|
as arguments to the factory requests to specify how the constraint
|
||||||
|
lifetimes should be managed.
|
||||||
|
</description>
|
||||||
|
<entry name="oneshot" value="1">
|
||||||
|
<description summary="the pointer constraint is defunct once deactivated">
|
||||||
|
A oneshot pointer constraint will never reactivate once it has been
|
||||||
|
deactivated. See the corresponding deactivation event
|
||||||
|
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
|
||||||
|
details.
|
||||||
|
</description>
|
||||||
|
</entry>
|
||||||
|
<entry name="persistent" value="2">
|
||||||
|
<description summary="the pointer constraint may reactivate">
|
||||||
|
A persistent pointer constraint may again reactivate once it has
|
||||||
|
been deactivated. See the corresponding deactivation event
|
||||||
|
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
|
||||||
|
details.
|
||||||
|
</description>
|
||||||
|
</entry>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the pointer constraints manager object">
|
||||||
|
Used by the client to notify the server that it will no longer use this
|
||||||
|
pointer constraints object.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="lock_pointer">
|
||||||
|
<description summary="lock pointer to a position">
|
||||||
|
The lock_pointer request lets the client request to disable movements of
|
||||||
|
the virtual pointer (i.e. the cursor), effectively locking the pointer
|
||||||
|
to a position. This request may not take effect immediately; in the
|
||||||
|
future, when the compositor deems implementation-specific constraints
|
||||||
|
are satisfied, the pointer lock will be activated and the compositor
|
||||||
|
sends a locked event.
|
||||||
|
|
||||||
|
The protocol provides no guarantee that the constraints are ever
|
||||||
|
satisfied, and does not require the compositor to send an error if the
|
||||||
|
constraints cannot ever be satisfied. It is thus possible to request a
|
||||||
|
lock that will never activate.
|
||||||
|
|
||||||
|
There may not be another pointer constraint of any kind requested or
|
||||||
|
active on the surface for any of the wl_pointer objects of the seat of
|
||||||
|
the passed pointer when requesting a lock. If there is, an error will be
|
||||||
|
raised. See general pointer lock documentation for more details.
|
||||||
|
|
||||||
|
The intersection of the region passed with this request and the input
|
||||||
|
region of the surface is used to determine where the pointer must be
|
||||||
|
in order for the lock to activate. It is up to the compositor whether to
|
||||||
|
warp the pointer or require some kind of user interaction for the lock
|
||||||
|
to activate. If the region is null the surface input region is used.
|
||||||
|
|
||||||
|
A surface may receive pointer focus without the lock being activated.
|
||||||
|
|
||||||
|
The request creates a new object wp_locked_pointer which is used to
|
||||||
|
interact with the lock as well as receive updates about its state. See
|
||||||
|
the the description of wp_locked_pointer for further information.
|
||||||
|
|
||||||
|
Note that while a pointer is locked, the wl_pointer objects of the
|
||||||
|
corresponding seat will not emit any wl_pointer.motion events, but
|
||||||
|
relative motion events will still be emitted via wp_relative_pointer
|
||||||
|
objects of the same seat. wl_pointer.axis and wl_pointer.button events
|
||||||
|
are unaffected.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="zwp_locked_pointer_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"
|
||||||
|
summary="surface to lock pointer to"/>
|
||||||
|
<arg name="pointer" type="object" interface="wl_pointer"
|
||||||
|
summary="the pointer that should be locked"/>
|
||||||
|
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||||
|
summary="region of surface"/>
|
||||||
|
<arg name="lifetime" type="uint" enum="lifetime" summary="lock lifetime"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="confine_pointer">
|
||||||
|
<description summary="confine pointer to a region">
|
||||||
|
The confine_pointer request lets the client request to confine the
|
||||||
|
pointer cursor to a given region. This request may not take effect
|
||||||
|
immediately; in the future, when the compositor deems implementation-
|
||||||
|
specific constraints are satisfied, the pointer confinement will be
|
||||||
|
activated and the compositor sends a confined event.
|
||||||
|
|
||||||
|
The intersection of the region passed with this request and the input
|
||||||
|
region of the surface is used to determine where the pointer must be
|
||||||
|
in order for the confinement to activate. It is up to the compositor
|
||||||
|
whether to warp the pointer or require some kind of user interaction for
|
||||||
|
the confinement to activate. If the region is null the surface input
|
||||||
|
region is used.
|
||||||
|
|
||||||
|
The request will create a new object wp_confined_pointer which is used
|
||||||
|
to interact with the confinement as well as receive updates about its
|
||||||
|
state. See the the description of wp_confined_pointer for further
|
||||||
|
information.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="zwp_confined_pointer_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"
|
||||||
|
summary="surface to lock pointer to"/>
|
||||||
|
<arg name="pointer" type="object" interface="wl_pointer"
|
||||||
|
summary="the pointer that should be confined"/>
|
||||||
|
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||||
|
summary="region of surface"/>
|
||||||
|
<arg name="lifetime" type="uint" enum="lifetime" summary="confinement lifetime"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwp_locked_pointer_v1" version="1">
|
||||||
|
<description summary="receive relative pointer motion events">
|
||||||
|
The wp_locked_pointer interface represents a locked pointer state.
|
||||||
|
|
||||||
|
While the lock of this object is active, the wl_pointer objects of the
|
||||||
|
associated seat will not emit any wl_pointer.motion events.
|
||||||
|
|
||||||
|
This object will send the event 'locked' when the lock is activated.
|
||||||
|
Whenever the lock is activated, it is guaranteed that the locked surface
|
||||||
|
will already have received pointer focus and that the pointer will be
|
||||||
|
within the region passed to the request creating this object.
|
||||||
|
|
||||||
|
To unlock the pointer, send the destroy request. This will also destroy
|
||||||
|
the wp_locked_pointer object.
|
||||||
|
|
||||||
|
If the compositor decides to unlock the pointer the unlocked event is
|
||||||
|
sent. See wp_locked_pointer.unlock for details.
|
||||||
|
|
||||||
|
When unlocking, the compositor may warp the cursor position to the set
|
||||||
|
cursor position hint. If it does, it will not result in any relative
|
||||||
|
motion events emitted via wp_relative_pointer.
|
||||||
|
|
||||||
|
If the surface the lock was requested on is destroyed and the lock is not
|
||||||
|
yet activated, the wp_locked_pointer object is now defunct and must be
|
||||||
|
destroyed.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the locked pointer object">
|
||||||
|
Destroy the locked pointer object. If applicable, the compositor will
|
||||||
|
unlock the pointer.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_cursor_position_hint">
|
||||||
|
<description summary="set the pointer cursor position hint">
|
||||||
|
Set the cursor position hint relative to the top left corner of the
|
||||||
|
surface.
|
||||||
|
|
||||||
|
If the client is drawing its own cursor, it should update the position
|
||||||
|
hint to the position of its own cursor. A compositor may use this
|
||||||
|
information to warp the pointer upon unlock in order to avoid pointer
|
||||||
|
jumps.
|
||||||
|
|
||||||
|
The cursor position hint is double buffered. The new hint will only take
|
||||||
|
effect when the associated surface gets it pending state applied. See
|
||||||
|
wl_surface.commit for details.
|
||||||
|
</description>
|
||||||
|
<arg name="surface_x" type="fixed"
|
||||||
|
summary="surface-local x coordinate"/>
|
||||||
|
<arg name="surface_y" type="fixed"
|
||||||
|
summary="surface-local y coordinate"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_region">
|
||||||
|
<description summary="set a new lock region">
|
||||||
|
Set a new region used to lock the pointer.
|
||||||
|
|
||||||
|
The new lock region is double-buffered. The new lock region will
|
||||||
|
only take effect when the associated surface gets its pending state
|
||||||
|
applied. See wl_surface.commit for details.
|
||||||
|
|
||||||
|
For details about the lock region, see wp_locked_pointer.
|
||||||
|
</description>
|
||||||
|
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||||
|
summary="region of surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="locked">
|
||||||
|
<description summary="lock activation event">
|
||||||
|
Notification that the pointer lock of the seat's pointer is activated.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="unlocked">
|
||||||
|
<description summary="lock deactivation event">
|
||||||
|
Notification that the pointer lock of the seat's pointer is no longer
|
||||||
|
active. If this is a oneshot pointer lock (see
|
||||||
|
wp_pointer_constraints.lifetime) this object is now defunct and should
|
||||||
|
be destroyed. If this is a persistent pointer lock (see
|
||||||
|
wp_pointer_constraints.lifetime) this pointer lock may again
|
||||||
|
reactivate in the future.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwp_confined_pointer_v1" version="1">
|
||||||
|
<description summary="confined pointer object">
|
||||||
|
The wp_confined_pointer interface represents a confined pointer state.
|
||||||
|
|
||||||
|
This object will send the event 'confined' when the confinement is
|
||||||
|
activated. Whenever the confinement is activated, it is guaranteed that
|
||||||
|
the surface the pointer is confined to will already have received pointer
|
||||||
|
focus and that the pointer will be within the region passed to the request
|
||||||
|
creating this object. It is up to the compositor to decide whether this
|
||||||
|
requires some user interaction and if the pointer will warp to within the
|
||||||
|
passed region if outside.
|
||||||
|
|
||||||
|
To unconfine the pointer, send the destroy request. This will also destroy
|
||||||
|
the wp_confined_pointer object.
|
||||||
|
|
||||||
|
If the compositor decides to unconfine the pointer the unconfined event is
|
||||||
|
sent. The wp_confined_pointer object is at this point defunct and should
|
||||||
|
be destroyed.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the confined pointer object">
|
||||||
|
Destroy the confined pointer object. If applicable, the compositor will
|
||||||
|
unconfine the pointer.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_region">
|
||||||
|
<description summary="set a new confine region">
|
||||||
|
Set a new region used to confine the pointer.
|
||||||
|
|
||||||
|
The new confine region is double-buffered. The new confine region will
|
||||||
|
only take effect when the associated surface gets its pending state
|
||||||
|
applied. See wl_surface.commit for details.
|
||||||
|
|
||||||
|
If the confinement is active when the new confinement region is applied
|
||||||
|
and the pointer ends up outside of newly applied region, the pointer may
|
||||||
|
warped to a position within the new confinement region. If warped, a
|
||||||
|
wl_pointer.motion event will be emitted, but no
|
||||||
|
wp_relative_pointer.relative_motion event.
|
||||||
|
|
||||||
|
The compositor may also, instead of using the new region, unconfine the
|
||||||
|
pointer.
|
||||||
|
|
||||||
|
For details about the confine region, see wp_confined_pointer.
|
||||||
|
</description>
|
||||||
|
<arg name="region" type="object" interface="wl_region" allow-null="true"
|
||||||
|
summary="region of surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="confined">
|
||||||
|
<description summary="pointer confined">
|
||||||
|
Notification that the pointer confinement of the seat's pointer is
|
||||||
|
activated.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="unconfined">
|
||||||
|
<description summary="pointer unconfined">
|
||||||
|
Notification that the pointer confinement of the seat's pointer is no
|
||||||
|
longer active. If this is a oneshot pointer confinement (see
|
||||||
|
wp_pointer_constraints.lifetime) this object is now defunct and should
|
||||||
|
be destroyed. If this is a persistent pointer confinement (see
|
||||||
|
wp_pointer_constraints.lifetime) this pointer confinement may again
|
||||||
|
reactivate in the future.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
</protocol>
|
||||||
270
protocols/wlr-foreign-toplevel-management-unstable-v1.xml
Normal file
270
protocols/wlr-foreign-toplevel-management-unstable-v1.xml
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="wlr_foreign_toplevel_management_unstable_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2018 Ilia Bozhinov
|
||||||
|
|
||||||
|
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_foreign_toplevel_manager_v1" version="3">
|
||||||
|
<description summary="list and control opened apps">
|
||||||
|
The purpose of this protocol is to enable the creation of taskbars
|
||||||
|
and docks by providing them with a list of opened applications and
|
||||||
|
letting them request certain actions on them, like maximizing, etc.
|
||||||
|
|
||||||
|
After a client binds the zwlr_foreign_toplevel_manager_v1, each opened
|
||||||
|
toplevel window will be sent via the toplevel event
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<event name="toplevel">
|
||||||
|
<description summary="a toplevel has been created">
|
||||||
|
This event is emitted whenever a new toplevel window is created. It
|
||||||
|
is emitted for all toplevels, regardless of the app that has created
|
||||||
|
them.
|
||||||
|
|
||||||
|
All initial details of the toplevel(title, app_id, states, etc.) will
|
||||||
|
be sent immediately after this event via the corresponding events in
|
||||||
|
zwlr_foreign_toplevel_handle_v1.
|
||||||
|
</description>
|
||||||
|
<arg name="toplevel" type="new_id" interface="zwlr_foreign_toplevel_handle_v1"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="stop">
|
||||||
|
<description summary="stop sending events">
|
||||||
|
Indicates the client no longer wishes to receive events for new toplevels.
|
||||||
|
However the compositor may emit further toplevel_created events, until
|
||||||
|
the finished event is emitted.
|
||||||
|
|
||||||
|
The client must not send any more requests after this one.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="finished">
|
||||||
|
<description summary="the compositor has finished with the toplevel manager">
|
||||||
|
This event indicates that the compositor is done sending events to the
|
||||||
|
zwlr_foreign_toplevel_manager_v1. The server will destroy the object
|
||||||
|
immediately after sending this request, so it will become invalid and
|
||||||
|
the client should free any resources associated with it.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwlr_foreign_toplevel_handle_v1" version="3">
|
||||||
|
<description summary="an opened toplevel">
|
||||||
|
A zwlr_foreign_toplevel_handle_v1 object represents an opened toplevel
|
||||||
|
window. Each app may have multiple opened toplevels.
|
||||||
|
|
||||||
|
Each toplevel has a list of outputs it is visible on, conveyed to the
|
||||||
|
client with the output_enter and output_leave events.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<event name="title">
|
||||||
|
<description summary="title change">
|
||||||
|
This event is emitted whenever the title of the toplevel changes.
|
||||||
|
</description>
|
||||||
|
<arg name="title" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="app_id">
|
||||||
|
<description summary="app-id change">
|
||||||
|
This event is emitted whenever the app-id of the toplevel changes.
|
||||||
|
</description>
|
||||||
|
<arg name="app_id" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="output_enter">
|
||||||
|
<description summary="toplevel entered an output">
|
||||||
|
This event is emitted whenever the toplevel becomes visible on
|
||||||
|
the given output. A toplevel may be visible on multiple outputs.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="object" interface="wl_output"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="output_leave">
|
||||||
|
<description summary="toplevel left an output">
|
||||||
|
This event is emitted whenever the toplevel stops being visible on
|
||||||
|
the given output. It is guaranteed that an entered-output event
|
||||||
|
with the same output has been emitted before this event.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="object" interface="wl_output"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="set_maximized">
|
||||||
|
<description summary="requests that the toplevel be maximized">
|
||||||
|
Requests that the toplevel be maximized. If the maximized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_maximized">
|
||||||
|
<description summary="requests that the toplevel be unmaximized">
|
||||||
|
Requests that the toplevel be unmaximized. If the maximized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_minimized">
|
||||||
|
<description summary="requests that the toplevel be minimized">
|
||||||
|
Requests that the toplevel be minimized. If the minimized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_minimized">
|
||||||
|
<description summary="requests that the toplevel be unminimized">
|
||||||
|
Requests that the toplevel be unminimized. If the minimized state actually
|
||||||
|
changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="activate">
|
||||||
|
<description summary="activate the toplevel">
|
||||||
|
Request that this toplevel be activated on the given seat.
|
||||||
|
There is no guarantee the toplevel will be actually activated.
|
||||||
|
</description>
|
||||||
|
<arg name="seat" type="object" interface="wl_seat"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="state">
|
||||||
|
<description summary="types of states on the toplevel">
|
||||||
|
The different states that a toplevel can have. These have the same meaning
|
||||||
|
as the states with the same names defined in xdg-toplevel
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<entry name="maximized" value="0" summary="the toplevel is maximized"/>
|
||||||
|
<entry name="minimized" value="1" summary="the toplevel is minimized"/>
|
||||||
|
<entry name="activated" value="2" summary="the toplevel is active"/>
|
||||||
|
<entry name="fullscreen" value="3" summary="the toplevel is fullscreen" since="2"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="state">
|
||||||
|
<description summary="the toplevel state changed">
|
||||||
|
This event is emitted immediately after the zlw_foreign_toplevel_handle_v1
|
||||||
|
is created and each time the toplevel state changes, either because of a
|
||||||
|
compositor action or because of a request in this protocol.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="state" type="array"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="done">
|
||||||
|
<description summary="all information about the toplevel has been sent">
|
||||||
|
This event is sent after all changes in the toplevel state have been
|
||||||
|
sent.
|
||||||
|
|
||||||
|
This allows changes to the zwlr_foreign_toplevel_handle_v1 properties
|
||||||
|
to be seen as atomic, even if they happen via multiple events.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="close">
|
||||||
|
<description summary="request that the toplevel be closed">
|
||||||
|
Send a request to the toplevel to close itself. The compositor would
|
||||||
|
typically use a shell-specific method to carry out this request, for
|
||||||
|
example by sending the xdg_toplevel.close event. However, this gives
|
||||||
|
no guarantees the toplevel will actually be destroyed. If and when
|
||||||
|
this happens, the zwlr_foreign_toplevel_handle_v1.closed event will
|
||||||
|
be emitted.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_rectangle">
|
||||||
|
<description summary="the rectangle which represents the toplevel">
|
||||||
|
The rectangle of the surface specified in this request corresponds to
|
||||||
|
the place where the app using this protocol represents the given toplevel.
|
||||||
|
It can be used by the compositor as a hint for some operations, e.g
|
||||||
|
minimizing. The client is however not required to set this, in which
|
||||||
|
case the compositor is free to decide some default value.
|
||||||
|
|
||||||
|
If the client specifies more than one rectangle, only the last one is
|
||||||
|
considered.
|
||||||
|
|
||||||
|
The dimensions are given in surface-local coordinates.
|
||||||
|
Setting width=height=0 removes the already-set rectangle.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
<arg name="x" type="int"/>
|
||||||
|
<arg name="y" type="int"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="invalid_rectangle" value="0"
|
||||||
|
summary="the provided rectangle is invalid"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="closed">
|
||||||
|
<description summary="this toplevel has been destroyed">
|
||||||
|
This event means the toplevel has been destroyed. It is guaranteed there
|
||||||
|
won't be any more events for this zwlr_foreign_toplevel_handle_v1. The
|
||||||
|
toplevel itself becomes inert so any requests will be ignored except the
|
||||||
|
destroy request.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the zwlr_foreign_toplevel_handle_v1 object">
|
||||||
|
Destroys the zwlr_foreign_toplevel_handle_v1 object.
|
||||||
|
|
||||||
|
This request should be called either when the client does not want to
|
||||||
|
use the toplevel anymore or after the closed event to finalize the
|
||||||
|
destruction of the object.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 2 additions -->
|
||||||
|
|
||||||
|
<request name="set_fullscreen" since="2">
|
||||||
|
<description summary="request that the toplevel be fullscreened">
|
||||||
|
Requests that the toplevel be fullscreened on the given output. If the
|
||||||
|
fullscreen state and/or the outputs the toplevel is visible on actually
|
||||||
|
change, this will be indicated by the state and output_enter/leave
|
||||||
|
events.
|
||||||
|
|
||||||
|
The output parameter is only a hint to the compositor. Also, if output
|
||||||
|
is NULL, the compositor should decide which output the toplevel will be
|
||||||
|
fullscreened on, if at all.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="unset_fullscreen" since="2">
|
||||||
|
<description summary="request that the toplevel be unfullscreened">
|
||||||
|
Requests that the toplevel be unfullscreened. If the fullscreen state
|
||||||
|
actually changes, this will be indicated by the state event.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Version 3 additions -->
|
||||||
|
|
||||||
|
<event name="parent" since="3">
|
||||||
|
<description summary="parent change">
|
||||||
|
This event is emitted whenever the parent of the toplevel changes.
|
||||||
|
|
||||||
|
No event is emitted when the parent handle is destroyed by the client.
|
||||||
|
</description>
|
||||||
|
<arg name="parent" type="object" interface="zwlr_foreign_toplevel_handle_v1" allow-null="true"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
||||||
390
protocols/wlr-layer-shell-unstable-v1.xml
Normal file
390
protocols/wlr-layer-shell-unstable-v1.xml
Normal file
|
|
@ -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="namespace" 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>
|
||||||
35
util.c
Normal file
35
util.c
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* See LICENSE.dwm file for copyright and license details. */
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
die(const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
||||||
|
fputc(' ', stderr);
|
||||||
|
perror(NULL);
|
||||||
|
} else {
|
||||||
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ecalloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (!(p = calloc(nmemb, size)))
|
||||||
|
die("calloc:");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
4
util.h
Normal file
4
util.h
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/* See LICENSE.dwm file for copyright and license details. */
|
||||||
|
|
||||||
|
void die(const char *fmt, ...);
|
||||||
|
void *ecalloc(size_t nmemb, size_t size);
|
||||||
163
waybar/config
Executable file
163
waybar/config
Executable file
|
|
@ -0,0 +1,163 @@
|
||||||
|
{
|
||||||
|
"layer": "bottom",
|
||||||
|
"position": "top",
|
||||||
|
"height": 62,
|
||||||
|
"spacing": 5,
|
||||||
|
|
||||||
|
"margin-bottom":-11,
|
||||||
|
"modules-left": ["dwl/tags","wlr/taskbar","dwl/window"],
|
||||||
|
"modules-right": ["custom/notification","tray","network","cpu","temperature","memory","clock","pulseaudio","backlight","battery"],
|
||||||
|
"dwl/tags": {
|
||||||
|
"num-tags":9,
|
||||||
|
"hide-unused-tag":true
|
||||||
|
},
|
||||||
|
"custom/notification": {
|
||||||
|
"tooltip": false,
|
||||||
|
"format": "{icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"notification": "<span foreground='red'><sup></sup></span>",
|
||||||
|
"none": "",
|
||||||
|
"dnd-notification": "<span foreground='red'><sup></sup></span>",
|
||||||
|
"dnd-none": "",
|
||||||
|
"inhibited-notification": "<span foreground='red'><sup></sup></span>",
|
||||||
|
"inhibited-none": "",
|
||||||
|
"dnd-inhibited-notification": "<span foreground='red'><sup></sup></span>",
|
||||||
|
"dnd-inhibited-none": ""
|
||||||
|
},
|
||||||
|
"return-type": "json",
|
||||||
|
"exec-if": "which swaync-client",
|
||||||
|
"exec": "swaync-client -swb",
|
||||||
|
"on-click": "sleep 0.1s && swaync-client -t -sw",
|
||||||
|
"on-click-right": "swaync-client -d -sw",
|
||||||
|
"escape": true
|
||||||
|
},
|
||||||
|
"wlr/taskbar": {
|
||||||
|
"format": "{icon}",
|
||||||
|
"icon-size": 24,
|
||||||
|
"all-outputs": false,
|
||||||
|
"tooltip-format": "{title}",
|
||||||
|
"markup": true,
|
||||||
|
"on-click": "activate",
|
||||||
|
"on-click-right": "close",
|
||||||
|
"ignore-list": ["Rofi","wofi"]
|
||||||
|
},
|
||||||
|
"pulseaudio": {
|
||||||
|
"interval":1,
|
||||||
|
"scroll-step": 1,
|
||||||
|
"format": "{volume}%{icon}",
|
||||||
|
"format-bluetooth": "{volume}%",
|
||||||
|
"format-bluetooth-muted": "{volume}%",
|
||||||
|
"format-muted": "{volume}%{icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"default": ["", "", ""]
|
||||||
|
},
|
||||||
|
"on-click": "blueman-manager",
|
||||||
|
"on-click-right":"amixer set Master toggle",
|
||||||
|
},
|
||||||
|
"keyboard-state": {
|
||||||
|
"interval":1,
|
||||||
|
"numlock": true,
|
||||||
|
"capslock": true,
|
||||||
|
"format": "{name} {icon}",
|
||||||
|
"format-icons": {
|
||||||
|
"locked": "",
|
||||||
|
"unlocked": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
"interval":1,
|
||||||
|
"icon-size": 21,
|
||||||
|
"spacing": 10
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
//"format": "{:%I:%M %p}",
|
||||||
|
"format": "{:%H:%M} " ,
|
||||||
|
"format-alt": "{:%A, %b %d} ",
|
||||||
|
"tooltip-format": "{:%Y}",
|
||||||
|
// "tooltip-format": "<tt><small>{calendar}</small></tt>",
|
||||||
|
"on-click-right": "gnome-calendar",
|
||||||
|
"calendar": {
|
||||||
|
"mode" : "year",
|
||||||
|
"mode-mon-col" : 3,
|
||||||
|
"weeks-pos" : "right",
|
||||||
|
"on-scroll" : 1,
|
||||||
|
"on-click-right": "gnome-calendar",
|
||||||
|
"format": {
|
||||||
|
"months": "<span color='#ffead3'><b>{}</b></span>",
|
||||||
|
"days": "<span color='#ecc6d9'><b>{}</b></span>",
|
||||||
|
"weeks": "<span color='#99ffdd'><b>W{}</b></span>",
|
||||||
|
"weekdays": "<span color='#ffcc66'><b>{}</b></span>",
|
||||||
|
"today": "<span color='#ff6699'><b><u>{}</u></b></span>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cpu": {
|
||||||
|
"interval": 2,
|
||||||
|
"format": "{load}% ",
|
||||||
|
"on-click-right":"gnome-system-monitor",
|
||||||
|
"on-click":"nwg-drawer -ovl"
|
||||||
|
// "on-click-right":"bash ~/.config/eww/scripts/launcher toggle_menu quicksettings",
|
||||||
|
// "max-length": 10
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
"interval":2,
|
||||||
|
"format": "{}% ",
|
||||||
|
"on-click":"GDK_BACKEND=x11 nemo",
|
||||||
|
"on-click-right":"cliphist list | rofi -dmenu -normal-window | cliphist decode | wl-copy"
|
||||||
|
// "on-click-right":"clipman pick -t wofi"
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"thermal-zone": 2,
|
||||||
|
"hwmon-path": "/sys/class/hwmon/hwmon1/temp1_input",
|
||||||
|
"critical-threshold": 10,
|
||||||
|
"format-critical": "{temperatureC}°C",
|
||||||
|
"format": "",
|
||||||
|
"on-click":"rofi -normal-window -theme ~/.config/rofi/themes/fancy2.rasi -modi blocks -show blocks -blocks-wrap ~/.config/rofi/history.py",
|
||||||
|
"on-click-right":"rofi -normal-window -theme ~/.config/rofi/themes/fancy2.rasi -modi blocks -show blocks -blocks-wrap ~/.config/rofi/recentfile.py"
|
||||||
|
// "on-click":"$DWL/wofi/history_wofi.py",
|
||||||
|
// "on-click-right":"$DWL/wofi/recentfile_wofi.py"
|
||||||
|
},
|
||||||
|
"backlight": {
|
||||||
|
"interval":2,
|
||||||
|
"device": "amdgpu_bl0",
|
||||||
|
"format": "{percent}% {icon}",
|
||||||
|
"format-icons": ["",""],
|
||||||
|
"on-scroll-up":"~/.config/hypr/scripts/lightup",
|
||||||
|
"on-scroll-down":"~/.config/hypr/scripts/lightdown",
|
||||||
|
"smooth-scrolling-threshold":1
|
||||||
|
},
|
||||||
|
"battery": {
|
||||||
|
"bat": "BAT0",
|
||||||
|
"interval": 60,
|
||||||
|
"states": {
|
||||||
|
"warning": 30,
|
||||||
|
"critical": 10
|
||||||
|
},
|
||||||
|
"format": "{capacity}% {icon}",
|
||||||
|
"format-icons": ["", "", "", "", ""],
|
||||||
|
"on-click-right":"~/.config/eww/System-Menu/launch",
|
||||||
|
"on-click":"wlogout --protocol layer-shell -b 6"
|
||||||
|
// "on-click":"/usr/local/bin/eww open-many --toggle background-closer powermenu"
|
||||||
|
// "max-length": 25
|
||||||
|
},
|
||||||
|
"disk": {
|
||||||
|
"interval": 30,
|
||||||
|
//"format": "",
|
||||||
|
"path": "/",
|
||||||
|
//"format-alt-click": "click",
|
||||||
|
"format": "{percentage_used}% ",
|
||||||
|
"on-click":"nemo",
|
||||||
|
//"tooltip": true,
|
||||||
|
"tooltip-format": "{used} used out of {total} on {path} ({percentage_used}%)",
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"interval": 2,
|
||||||
|
"format-wifi": "{essid} ({signalStrength}%)\uf1eb",
|
||||||
|
"format-ethernet": " {ifname}",
|
||||||
|
"format-linked": "\uf059 No IP ({ifname})",
|
||||||
|
"format-disconnected": "\uf071 Disconnected",
|
||||||
|
"tooltip-format": "{ifname} {ipaddr}/{cidr} via {gwaddr}",
|
||||||
|
"format-alt": "\uf1eb↓{bandwidthDownBytes} ↑{bandwidthUpBytes}",
|
||||||
|
"on-click-right":"~/.config/dwl/rofi/networkmanager_dmenu"
|
||||||
|
}
|
||||||
|
}
|
||||||
663
waybar/style.css
Executable file
663
waybar/style.css
Executable file
|
|
@ -0,0 +1,663 @@
|
||||||
|
* {
|
||||||
|
font-family: CartographCF Nerd Font,FontAwesome, Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip {
|
||||||
|
background: #3C3A38;
|
||||||
|
border: 2px solid #85796F;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip label {
|
||||||
|
color: #EBDBB2;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tags{
|
||||||
|
background-color: transparent;
|
||||||
|
margin-top: 14px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
margin-right: 1px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tags button{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -3 5 5px;
|
||||||
|
background-color: #fff ;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
padding-top: 1px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-right: 7px;
|
||||||
|
padding-left: 7px;
|
||||||
|
background-size: 300% 300%;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #a585cd ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid #d6cdcd;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#tags button.occupied{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -3 5 5px;
|
||||||
|
background-color: #fff ;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
padding-top: 1px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-right: 7px;
|
||||||
|
padding-left: 7px;
|
||||||
|
background-size: 300% 300%;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #a585cd ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid #d6cdcd;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tags button.focused{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -3 5 5px;
|
||||||
|
background-color: rgb(186, 142, 213);
|
||||||
|
padding-bottom: 1px;
|
||||||
|
padding-top: 1px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
background-size: 300% 300%;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #fff ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(143, 102, 168);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tags button.urgent{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -3 5 5px;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
padding-top: 1px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-right: 7px;
|
||||||
|
padding-left: 7px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background: rgb(171, 101, 101);
|
||||||
|
/* background: linear-gradient(45deg, rgba(202,158,230,1) 0%, rgba(245,194,231,1) 43%, rgba(180,190,254,1) 80%, rgba(137,180,250,1) 100%); */
|
||||||
|
background-size: 300% 300%;
|
||||||
|
/* animation: gradient 10s ease infinite; */
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(105, 57, 57);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#taskbar{
|
||||||
|
background-color: transparent;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-left: 1px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#taskbar button{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
/* text-shadow: 0 0 2px rgba(0, 0, 0, 0.8); */
|
||||||
|
background-color: rgb(237, 196, 147);
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #ededed ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(193, 146, 103);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#taskbar button.minimized{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
background-color: rgb(146, 140, 151);
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #cba6f7 ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(98, 97, 99);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#taskbar button.urgent{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
background-color: rgb(238, 92, 92);
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #cba6f7 ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(183, 63, 63);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#taskbar button.active{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
background-color: rgb(186, 238, 225);
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #cba6f7 ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(131, 184, 171);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar.empty #window {
|
||||||
|
background-color: transparent;
|
||||||
|
color: transparent;
|
||||||
|
border-bottom:none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding-right: 0px;
|
||||||
|
padding-left: 0px;
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#window{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
/* text-shadow: 0 0 2px rgba(0, 0, 0, 0.8); */
|
||||||
|
background-color: rgb(237, 196, 147);
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
margin-right: 8px;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: rgb(63, 37, 5);
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid rgb(193, 146, 103);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#custom-notification {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -3 5 5px;
|
||||||
|
background-color: #cb7cc6 ;
|
||||||
|
padding-bottom: 1px;
|
||||||
|
padding-top: 1px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
|
background-size: 300% 300%;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: rgb(244, 240, 233) ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 6px solid #904e8b;
|
||||||
|
border-radius: 15px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gradient {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#clock,
|
||||||
|
#battery,
|
||||||
|
#cpu,
|
||||||
|
#memory,
|
||||||
|
#disk,
|
||||||
|
#temperature,
|
||||||
|
#backlight,
|
||||||
|
#network,
|
||||||
|
#pulseaudio,
|
||||||
|
#custom-media,
|
||||||
|
#tray,
|
||||||
|
#mode,
|
||||||
|
#idle_inhibitor,
|
||||||
|
#custom-expand,
|
||||||
|
#custom-cycle_wall,
|
||||||
|
#custom-ss,
|
||||||
|
#custom-dynamic_pill,
|
||||||
|
#mpd {
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: #cdd6f4;
|
||||||
|
color: #516079;
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.116) 2 2 5 2px;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-dynamic_pill.low{
|
||||||
|
background: rgb(148,226,213);
|
||||||
|
background: linear-gradient(52deg, rgba(148,226,213,1) 0%, rgba(137,220,235,1) 19%, rgba(116,199,236,1) 43%, rgba(137,180,250,1) 56%, rgba(180,190,254,1) 80%, rgba(186,187,241,1) 100%);
|
||||||
|
background-size: 300% 300%;
|
||||||
|
/* text-shadow: 0 0 5px rgba(0, 0, 0, 0.377); */
|
||||||
|
animation: gradient 15s ease infinite;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
#custom-dynamic_pill.normal{
|
||||||
|
background: rgb(166,209,137);
|
||||||
|
background: linear-gradient(52deg, rgba(166,209,137,1) 0%, rgba(166,227,161,1) 26%, rgba(148,226,213,1) 65%, rgba(129,200,190,1) 100%);
|
||||||
|
background-size: 300% 300%;
|
||||||
|
animation: gradient 15s ease infinite;
|
||||||
|
/* text-shadow: 0 0 5px rgba(0, 0, 0, 0.377); */
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
#custom-dynamic_pill.critical{
|
||||||
|
background: rgb(235,160,172);
|
||||||
|
background: linear-gradient(52deg, rgba(235,160,172,1) 0%, rgba(243,139,168,1) 30%, rgba(231,130,132,1) 48%, rgba(250,179,135,1) 77%, rgba(249,226,175,1) 100%);
|
||||||
|
background-size: 300% 300%;
|
||||||
|
animation: gradient 15s ease infinite;
|
||||||
|
/* text-shadow: 0 0 5px rgba(0, 0, 0, 0.377); */
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#custom-dynamic_pill.playing{
|
||||||
|
background: rgb(249,226,175);
|
||||||
|
background: linear-gradient(45deg, rgba(249,226,175,1) 0%, rgba(245,194,231,1) 20%, rgba(180,190,254,1) 100%);
|
||||||
|
background-size: 300% 300%;
|
||||||
|
animation: gradient 15s ease infinite;
|
||||||
|
/* text-shadow: 0 0 5px rgba(0, 0, 0, 0.377); */
|
||||||
|
font-weight: 900;
|
||||||
|
color: #fff ;
|
||||||
|
}
|
||||||
|
#custom-dynamic_pill.paused{
|
||||||
|
background: #fff ;
|
||||||
|
font-weight: bolder;
|
||||||
|
color: #b4befe;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-ss{
|
||||||
|
background: #fff;
|
||||||
|
color: rgba(203,166,247,1);
|
||||||
|
font-weight: bolder;
|
||||||
|
padding: 5px;
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-cycle_wall{
|
||||||
|
background: rgb(245,194,231);
|
||||||
|
/* background: linear-gradient(45deg, rgba(245,194,231,1) 0%, rgba(203,166,247,1) 0%, rgba(243,139,168,1) 13%, rgba(235,160,172,1) 26%, rgba(250,179,135,1) 34%, rgba(249,226,175,1) 49%, rgba(166,227,161,1) 65%, rgba(148,226,213,1) 77%, rgba(137,220,235,1) 82%, rgba(116,199,236,1) 88%, rgba(137,180,250,1) 95%); */
|
||||||
|
color: #fff;
|
||||||
|
background-size: 500% 500%;
|
||||||
|
/* animation: gradient 7s linear infinite; */
|
||||||
|
font-weight: bolder;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#clock {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
background: rgb(179, 42, 142);
|
||||||
|
/* background: linear-gradient(45deg, rgb(99, 6, 74) 0%, rgba(203,166,247,1) 64%, rgba(202,158,230,1) 100%); */
|
||||||
|
margin-left: 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
min-width: 50px;
|
||||||
|
color: #f8e1b7 ;
|
||||||
|
background-size: 300% 300%;
|
||||||
|
/* animation: gradient 20s ease infinite; */
|
||||||
|
font-size: 20px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
padding-right: 15px;
|
||||||
|
font-weight: bolder;
|
||||||
|
padding-left: 15px;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid rgb(155, 32, 122);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.charging, #battery.plugged {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
min-width: 70px;
|
||||||
|
color: #bdf8da;
|
||||||
|
background: #495026 ;
|
||||||
|
margin-right: 10px;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #3a401d;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
background-color: #07683e;
|
||||||
|
color:#eae4d0;
|
||||||
|
font-weight: bolder;
|
||||||
|
font-size: 20px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
margin-right: 10px;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #297f5a;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
to {
|
||||||
|
background-color: #f9e2af;
|
||||||
|
color:#96804e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.critical:not(.charging) {
|
||||||
|
background-color: #f38ba8;
|
||||||
|
color:#bf5673;
|
||||||
|
animation-name: blink;
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-timing-function: linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
label:focus {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#cpu {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
min-width: 80px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background: rgb(39, 154, 207);
|
||||||
|
/* background: linear-gradient(52deg, rgba(180,190,254,1) 0%, rgba(137,220,235,1) 32%, rgba(137,180,250,1) 72%, rgba(166,227,161,1) 100%); */
|
||||||
|
background-size: 300% 300%;
|
||||||
|
/* animation: gradient 20s ease infinite; */
|
||||||
|
/* text-shadow: 0 10 5px rgba(0, 0, 0, 0.8); */
|
||||||
|
/* background-color: #b4befe; */
|
||||||
|
color: #edebe6;
|
||||||
|
font-weight: bolder;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid rgb(58, 125, 156);
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#memory {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
min-width: 60px;
|
||||||
|
background-color: #cba6f7;
|
||||||
|
color: #55406e;
|
||||||
|
font-weight: bolder;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #9172b6;
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#disk {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
background-color: #cca45a;
|
||||||
|
color: #572e05;
|
||||||
|
}
|
||||||
|
|
||||||
|
#backlight {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
color: #090427;
|
||||||
|
min-width: 40px;
|
||||||
|
background-color: #c3cac2 ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #8a9488;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
color:#000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.disabled{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #45475a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.disconnected{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background: rgb(243,139,168);
|
||||||
|
/* background: linear-gradient(45deg, rgba(243,139,168,1) 0%, rgba(250,179,135,1) 100%); */
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bolder;
|
||||||
|
padding-right: 11px;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid rgb(213, 115, 142);
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.linked, #network.wifi{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #a6e3a1 ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #79b574;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.ethernet{
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #a6e3a1 ;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #79b574;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pulseaudio {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
min-width: 40px;
|
||||||
|
background-color: #fab387;
|
||||||
|
color: #734a31;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #b87c57;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pulseaudio.muted {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #9f7154;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media {
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
color: #66cc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media.custom-spotify {
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
background-color: #66cc99;
|
||||||
|
}
|
||||||
|
|
||||||
|
#custom-media.custom-vlc {
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
background-color: #ffa000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#temperature {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #f9e2af;
|
||||||
|
color:#96804e;
|
||||||
|
}
|
||||||
|
#temperature.critical {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
font-weight: bolder;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #ce91a0 ;
|
||||||
|
color:#50393f;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #a26a79;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
background-color: #96d5dd;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 7px solid #66a1a9;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray > .passive {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
-gtk-icon-effect: dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tray > .needs-attention {
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.5) 0 -6 3 1px;
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
-gtk-icon-effect: highlight;
|
||||||
|
background-color: #eb4d4b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor {
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
background-color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#idle_inhibitor.activated {
|
||||||
|
margin-right: 3px;
|
||||||
|
margin-left: 1px;
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
color: #2d3436;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd {
|
||||||
|
background-color: #66cc99;
|
||||||
|
color: #2a5c45;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.disconnected {
|
||||||
|
background-color: #f53c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.stopped {
|
||||||
|
background-color: #90b1b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mpd.paused {
|
||||||
|
background-color: #51a37a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#language {
|
||||||
|
background: #00b093;
|
||||||
|
color: #740864;
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 0 5px;
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state {
|
||||||
|
background: #97e1ad;
|
||||||
|
color: #000000;
|
||||||
|
padding: 0 0px;
|
||||||
|
margin: 0 5px;
|
||||||
|
min-width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state > label {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#keyboard-state > label.locked {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
712
wlr_foreign_toplevel_management_v1.c
Executable file
712
wlr_foreign_toplevel_management_v1.c
Executable file
|
|
@ -0,0 +1,712 @@
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
||||||
|
#include <wlr/types/wlr_seat.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include "wlr-foreign-toplevel-management-unstable-v1-protocol.h"
|
||||||
|
|
||||||
|
#define FOREIGN_TOPLEVEL_MANAGEMENT_V1_VERSION 3
|
||||||
|
|
||||||
|
static const struct zwlr_foreign_toplevel_handle_v1_interface toplevel_handle_impl;
|
||||||
|
|
||||||
|
static struct wlr_foreign_toplevel_handle_v1 *toplevel_handle_from_resource(
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
assert(wl_resource_instance_of(resource,
|
||||||
|
&zwlr_foreign_toplevel_handle_v1_interface,
|
||||||
|
&toplevel_handle_impl));
|
||||||
|
return wl_resource_get_user_data(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_handle_send_maximized_event(struct wl_resource *resource,
|
||||||
|
bool state) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel =
|
||||||
|
toplevel_handle_from_resource(resource);
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_maximized_event event = {
|
||||||
|
.toplevel = toplevel,
|
||||||
|
.maximized = state,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.request_maximize, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_set_maximized(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
toplevel_handle_send_maximized_event(resource, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_unset_maximized(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
toplevel_handle_send_maximized_event(resource, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_send_minimized_event(struct wl_resource *resource,
|
||||||
|
bool state) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel =
|
||||||
|
toplevel_handle_from_resource(resource);
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_minimized_event event = {
|
||||||
|
.toplevel = toplevel,
|
||||||
|
.minimized = state,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.request_minimize, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_set_minimized(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
toplevel_send_minimized_event(resource, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_unset_minimized(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
toplevel_send_minimized_event(resource, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_send_fullscreen_event(struct wl_resource *resource,
|
||||||
|
bool state, struct wl_resource *output_resource) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel =
|
||||||
|
toplevel_handle_from_resource(resource);
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_output *output = NULL;
|
||||||
|
if (output_resource) {
|
||||||
|
output = wlr_output_from_resource(output_resource);
|
||||||
|
}
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_fullscreen_event event = {
|
||||||
|
.toplevel = toplevel,
|
||||||
|
.fullscreen = state,
|
||||||
|
.output = output,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.request_fullscreen, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_set_fullscreen(struct wl_client *client,
|
||||||
|
struct wl_resource *resource, struct wl_resource *output) {
|
||||||
|
toplevel_send_fullscreen_event(resource, true, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_unset_fullscreen(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
toplevel_send_fullscreen_event(resource, false, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_activate(struct wl_client *client,
|
||||||
|
struct wl_resource *resource, struct wl_resource *seat) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel =
|
||||||
|
toplevel_handle_from_resource(resource);
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat);
|
||||||
|
if (!seat_client) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_activated_event event = {
|
||||||
|
.toplevel = toplevel,
|
||||||
|
.seat = seat_client->seat,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.request_activate, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_close(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel =
|
||||||
|
toplevel_handle_from_resource(resource);
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.request_close, toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_set_rectangle(struct wl_client *client,
|
||||||
|
struct wl_resource *resource, struct wl_resource *surface,
|
||||||
|
int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel =
|
||||||
|
toplevel_handle_from_resource(resource);
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width < 0 || height < 0) {
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_ERROR_INVALID_RECTANGLE,
|
||||||
|
"invalid rectangle passed to set_rectangle: width/height < 0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_set_rectangle_event event = {
|
||||||
|
.toplevel = toplevel,
|
||||||
|
.surface = wlr_surface_from_resource(surface),
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.set_rectangle, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_handle_destroy(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwlr_foreign_toplevel_handle_v1_interface toplevel_handle_impl = {
|
||||||
|
.set_maximized = foreign_toplevel_handle_set_maximized,
|
||||||
|
.unset_maximized = foreign_toplevel_handle_unset_maximized,
|
||||||
|
.set_minimized = foreign_toplevel_handle_set_minimized,
|
||||||
|
.unset_minimized = foreign_toplevel_handle_unset_minimized,
|
||||||
|
.activate = foreign_toplevel_handle_activate,
|
||||||
|
.close = foreign_toplevel_handle_close,
|
||||||
|
.set_rectangle = foreign_toplevel_handle_set_rectangle,
|
||||||
|
.destroy = foreign_toplevel_handle_destroy,
|
||||||
|
.set_fullscreen = foreign_toplevel_handle_set_fullscreen,
|
||||||
|
.unset_fullscreen = foreign_toplevel_handle_unset_fullscreen,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void toplevel_idle_send_done(void *data) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel = data;
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel->resources) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_done(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel->idle_source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_update_idle_source(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel) {
|
||||||
|
if (toplevel->idle_source) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel->idle_source = wl_event_loop_add_idle(toplevel->manager->event_loop,
|
||||||
|
toplevel_idle_send_done, toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_title(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, const char *title) {
|
||||||
|
free(toplevel->title);
|
||||||
|
toplevel->title = strdup(title);
|
||||||
|
if (toplevel->title == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "failed to allocate memory for toplevel title");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel->resources) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_title(resource, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_update_idle_source(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_app_id(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, const char *app_id) {
|
||||||
|
free(toplevel->app_id);
|
||||||
|
toplevel->app_id = strdup(app_id);
|
||||||
|
if (toplevel->app_id == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "failed to allocate memory for toplevel app_id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel->resources) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_app_id(resource, app_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_update_idle_source(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_output_to_resource(struct wl_resource *resource,
|
||||||
|
struct wlr_output *output, bool enter) {
|
||||||
|
struct wl_client *client = wl_resource_get_client(resource);
|
||||||
|
struct wl_resource *output_resource;
|
||||||
|
|
||||||
|
wl_resource_for_each(output_resource, &output->resources) {
|
||||||
|
if (wl_resource_get_client(output_resource) == client) {
|
||||||
|
if (enter) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_output_enter(resource,
|
||||||
|
output_resource);
|
||||||
|
} else {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_output_leave(resource,
|
||||||
|
output_resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_send_output(struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wlr_output *output, bool enter) {
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel->resources) {
|
||||||
|
send_output_to_resource(resource, output, enter);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_update_idle_source(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_handle_output_bind(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output =
|
||||||
|
wl_container_of(listener, toplevel_output, output_bind);
|
||||||
|
struct wlr_output_event_bind *event = data;
|
||||||
|
struct wl_client *client = wl_resource_get_client(event->resource);
|
||||||
|
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel_output->toplevel->resources) {
|
||||||
|
if (wl_resource_get_client(resource) == client) {
|
||||||
|
send_output_to_resource(resource, toplevel_output->output, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_update_idle_source(toplevel_output->toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_handle_output_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output =
|
||||||
|
wl_container_of(listener, toplevel_output, output_destroy);
|
||||||
|
wlr_foreign_toplevel_handle_v1_output_leave(toplevel_output->toplevel,
|
||||||
|
toplevel_output->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_output_enter(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wlr_output *output) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output;
|
||||||
|
wl_list_for_each(toplevel_output, &toplevel->outputs, link) {
|
||||||
|
if (toplevel_output->output == output) {
|
||||||
|
return; // we have already sent output_enter event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_output =
|
||||||
|
calloc(1, sizeof(struct wlr_foreign_toplevel_handle_v1_output));
|
||||||
|
if (!toplevel_output) {
|
||||||
|
wlr_log(WLR_ERROR, "failed to allocate memory for toplevel output");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_output->output = output;
|
||||||
|
toplevel_output->toplevel = toplevel;
|
||||||
|
wl_list_insert(&toplevel->outputs, &toplevel_output->link);
|
||||||
|
|
||||||
|
toplevel_output->output_bind.notify = toplevel_handle_output_bind;
|
||||||
|
wl_signal_add(&output->events.bind, &toplevel_output->output_bind);
|
||||||
|
|
||||||
|
toplevel_output->output_destroy.notify = toplevel_handle_output_destroy;
|
||||||
|
wl_signal_add(&output->events.destroy, &toplevel_output->output_destroy);
|
||||||
|
|
||||||
|
toplevel_send_output(toplevel, output, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_output_destroy(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output) {
|
||||||
|
wl_list_remove(&toplevel_output->link);
|
||||||
|
wl_list_remove(&toplevel_output->output_bind.link);
|
||||||
|
wl_list_remove(&toplevel_output->output_destroy.link);
|
||||||
|
free(toplevel_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_output_leave(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wlr_output *output) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output_iterator;
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output = NULL;
|
||||||
|
|
||||||
|
wl_list_for_each(toplevel_output_iterator, &toplevel->outputs, link) {
|
||||||
|
if (toplevel_output_iterator->output == output) {
|
||||||
|
toplevel_output = toplevel_output_iterator;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toplevel_output) {
|
||||||
|
toplevel_send_output(toplevel, output, false);
|
||||||
|
toplevel_output_destroy(toplevel_output);
|
||||||
|
} else {
|
||||||
|
// XXX: log an error? crash?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fill_array_from_toplevel_state(struct wl_array *array,
|
||||||
|
uint32_t state) {
|
||||||
|
if (state & WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED) {
|
||||||
|
uint32_t *index = wl_array_add(array, sizeof(uint32_t));
|
||||||
|
if (index == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*index = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED;
|
||||||
|
}
|
||||||
|
if (state & WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED) {
|
||||||
|
uint32_t *index = wl_array_add(array, sizeof(uint32_t));
|
||||||
|
if (index == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*index = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED;
|
||||||
|
}
|
||||||
|
if (state & WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED) {
|
||||||
|
uint32_t *index = wl_array_add(array, sizeof(uint32_t));
|
||||||
|
if (index == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*index = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
|
||||||
|
}
|
||||||
|
if (state & WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN) {
|
||||||
|
uint32_t *index = wl_array_add(array, sizeof(uint32_t));
|
||||||
|
if (index == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*index = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_send_state(struct wlr_foreign_toplevel_handle_v1 *toplevel) {
|
||||||
|
struct wl_array states;
|
||||||
|
wl_array_init(&states);
|
||||||
|
bool r = fill_array_from_toplevel_state(&states, toplevel->state);
|
||||||
|
if (!r) {
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel->resources) {
|
||||||
|
wl_resource_post_no_memory(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_array_release(&states);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_resource *resource;
|
||||||
|
wl_resource_for_each(resource, &toplevel->resources) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_state(resource, &states);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_array_release(&states);
|
||||||
|
toplevel_update_idle_source(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_maximized(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, bool maximized) {
|
||||||
|
if (maximized == !!(toplevel->state &
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (maximized) {
|
||||||
|
toplevel->state |= WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED;
|
||||||
|
} else {
|
||||||
|
toplevel->state &= ~WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED;
|
||||||
|
}
|
||||||
|
toplevel_send_state(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_minimized(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, bool minimized) {
|
||||||
|
if (minimized == !!(toplevel->state &
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (minimized) {
|
||||||
|
toplevel->state |= WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED;
|
||||||
|
} else {
|
||||||
|
toplevel->state &= ~WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED;
|
||||||
|
}
|
||||||
|
toplevel_send_state(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_activated(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, bool activated) {
|
||||||
|
if (activated == !!(toplevel->state &
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (activated) {
|
||||||
|
toplevel->state |= WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
|
||||||
|
} else {
|
||||||
|
toplevel->state &= ~WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
|
||||||
|
}
|
||||||
|
toplevel_send_state(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_fullscreen(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 * toplevel, bool fullscreen) {
|
||||||
|
if (fullscreen == !!(toplevel->state &
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fullscreen) {
|
||||||
|
toplevel->state |= WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN;
|
||||||
|
} else {
|
||||||
|
toplevel->state &= ~WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN;
|
||||||
|
}
|
||||||
|
toplevel_send_state(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_resource_send_parent(
|
||||||
|
struct wl_resource *toplevel_resource,
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *parent) {
|
||||||
|
if (wl_resource_get_version(toplevel_resource) <
|
||||||
|
ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_PARENT_SINCE_VERSION) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct wl_client *client = wl_resource_get_client(toplevel_resource);
|
||||||
|
struct wl_resource *parent_resource = NULL;
|
||||||
|
if (parent) {
|
||||||
|
parent_resource = wl_resource_find_for_client(&parent->resources, client);
|
||||||
|
if (!parent_resource) {
|
||||||
|
/* don't send an event if this client destroyed the parent handle */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_parent(toplevel_resource,
|
||||||
|
parent_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_parent(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *parent) {
|
||||||
|
if (parent == toplevel->parent) {
|
||||||
|
/* only send parent event to the clients if there was a change */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct wl_resource *toplevel_resource, *tmp;
|
||||||
|
wl_resource_for_each_safe(toplevel_resource, tmp, &toplevel->resources) {
|
||||||
|
toplevel_resource_send_parent(toplevel_resource, parent);
|
||||||
|
}
|
||||||
|
toplevel->parent = parent;
|
||||||
|
toplevel_update_idle_source(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_destroy(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel) {
|
||||||
|
if (!toplevel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_signal_emit_mutable(&toplevel->events.destroy, toplevel);
|
||||||
|
|
||||||
|
struct wl_resource *resource, *tmp;
|
||||||
|
wl_resource_for_each_safe(resource, tmp, &toplevel->resources) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_closed(resource);
|
||||||
|
wl_resource_set_user_data(resource, NULL);
|
||||||
|
wl_list_remove(wl_resource_get_link(resource));
|
||||||
|
wl_list_init(wl_resource_get_link(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *toplevel_output, *tmp2;
|
||||||
|
wl_list_for_each_safe(toplevel_output, tmp2, &toplevel->outputs, link) {
|
||||||
|
toplevel_output_destroy(toplevel_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toplevel->idle_source) {
|
||||||
|
wl_event_source_remove(toplevel->idle_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_remove(&toplevel->link);
|
||||||
|
|
||||||
|
/* need to ensure no other toplevels hold a pointer to this one as
|
||||||
|
* a parent, so that a later call to foreign_toplevel_manager_bind()
|
||||||
|
* will not result in a segfault */
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *tl, *tmp3;
|
||||||
|
wl_list_for_each_safe(tl, tmp3, &toplevel->manager->toplevels, link) {
|
||||||
|
if (tl->parent == toplevel) {
|
||||||
|
/* Note: we send a parent signal to all clients in this case;
|
||||||
|
* the caller should first destroy the child handles if it
|
||||||
|
* wishes to avoid this behavior. */
|
||||||
|
wlr_foreign_toplevel_handle_v1_set_parent(tl, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(toplevel->title);
|
||||||
|
free(toplevel->app_id);
|
||||||
|
free(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_resource_destroy(struct wl_resource *resource) {
|
||||||
|
wl_list_remove(wl_resource_get_link(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_resource *create_toplevel_resource_for_resource(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wl_resource *manager_resource) {
|
||||||
|
struct wl_client *client = wl_resource_get_client(manager_resource);
|
||||||
|
struct wl_resource *resource = wl_resource_create(client,
|
||||||
|
&zwlr_foreign_toplevel_handle_v1_interface,
|
||||||
|
wl_resource_get_version(manager_resource), 0);
|
||||||
|
if (!resource) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_set_implementation(resource, &toplevel_handle_impl, toplevel,
|
||||||
|
foreign_toplevel_resource_destroy);
|
||||||
|
|
||||||
|
wl_list_insert(&toplevel->resources, wl_resource_get_link(resource));
|
||||||
|
zwlr_foreign_toplevel_manager_v1_send_toplevel(manager_resource, resource);
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *
|
||||||
|
wlr_foreign_toplevel_handle_v1_create(
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *manager) {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel = calloc(1,
|
||||||
|
sizeof(struct wlr_foreign_toplevel_handle_v1));
|
||||||
|
if (!toplevel) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_insert(&manager->toplevels, &toplevel->link);
|
||||||
|
toplevel->manager = manager;
|
||||||
|
|
||||||
|
wl_list_init(&toplevel->resources);
|
||||||
|
wl_list_init(&toplevel->outputs);
|
||||||
|
|
||||||
|
wl_signal_init(&toplevel->events.request_maximize);
|
||||||
|
wl_signal_init(&toplevel->events.request_minimize);
|
||||||
|
wl_signal_init(&toplevel->events.request_activate);
|
||||||
|
wl_signal_init(&toplevel->events.request_fullscreen);
|
||||||
|
wl_signal_init(&toplevel->events.request_close);
|
||||||
|
wl_signal_init(&toplevel->events.set_rectangle);
|
||||||
|
wl_signal_init(&toplevel->events.destroy);
|
||||||
|
|
||||||
|
struct wl_resource *manager_resource, *tmp;
|
||||||
|
wl_resource_for_each_safe(manager_resource, tmp, &manager->resources) {
|
||||||
|
create_toplevel_resource_for_resource(toplevel, manager_resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return toplevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwlr_foreign_toplevel_manager_v1_interface
|
||||||
|
foreign_toplevel_manager_impl;
|
||||||
|
|
||||||
|
static void foreign_toplevel_manager_handle_stop(struct wl_client *client,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
assert(wl_resource_instance_of(resource,
|
||||||
|
&zwlr_foreign_toplevel_manager_v1_interface,
|
||||||
|
&foreign_toplevel_manager_impl));
|
||||||
|
|
||||||
|
zwlr_foreign_toplevel_manager_v1_send_finished(resource);
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwlr_foreign_toplevel_manager_v1_interface
|
||||||
|
foreign_toplevel_manager_impl = {
|
||||||
|
.stop = foreign_toplevel_manager_handle_stop
|
||||||
|
};
|
||||||
|
|
||||||
|
static void foreign_toplevel_manager_resource_destroy(
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
wl_list_remove(wl_resource_get_link(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void toplevel_send_details_to_toplevel_resource(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wl_resource *resource) {
|
||||||
|
if (toplevel->title) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_title(resource, toplevel->title);
|
||||||
|
}
|
||||||
|
if (toplevel->app_id) {
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_app_id(resource, toplevel->app_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output *output;
|
||||||
|
wl_list_for_each(output, &toplevel->outputs, link) {
|
||||||
|
send_output_to_resource(resource, output->output, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_array states;
|
||||||
|
wl_array_init(&states);
|
||||||
|
bool r = fill_array_from_toplevel_state(&states, toplevel->state);
|
||||||
|
if (!r) {
|
||||||
|
wl_resource_post_no_memory(resource);
|
||||||
|
wl_array_release(&states);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_state(resource, &states);
|
||||||
|
wl_array_release(&states);
|
||||||
|
|
||||||
|
toplevel_resource_send_parent(resource, toplevel->parent);
|
||||||
|
|
||||||
|
zwlr_foreign_toplevel_handle_v1_send_done(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void foreign_toplevel_manager_bind(struct wl_client *client, void *data,
|
||||||
|
uint32_t version, uint32_t id) {
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *manager = data;
|
||||||
|
struct wl_resource *resource = wl_resource_create(client,
|
||||||
|
&zwlr_foreign_toplevel_manager_v1_interface, version, id);
|
||||||
|
if (!resource) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wl_resource_set_implementation(resource, &foreign_toplevel_manager_impl,
|
||||||
|
manager, foreign_toplevel_manager_resource_destroy);
|
||||||
|
|
||||||
|
wl_list_insert(&manager->resources, wl_resource_get_link(resource));
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, *tmp;
|
||||||
|
/* First loop: create a handle for all toplevels for all clients.
|
||||||
|
* Separation into two loops avoid the case where a child handle
|
||||||
|
* is created before a parent handle, so the parent relationship
|
||||||
|
* could not be sent to a client. */
|
||||||
|
wl_list_for_each_safe(toplevel, tmp, &manager->toplevels, link) {
|
||||||
|
create_toplevel_resource_for_resource(toplevel, resource);
|
||||||
|
}
|
||||||
|
/* Second loop: send details about each toplevel. */
|
||||||
|
wl_list_for_each_safe(toplevel, tmp, &manager->toplevels, link) {
|
||||||
|
struct wl_resource *toplevel_resource =
|
||||||
|
wl_resource_find_for_client(&toplevel->resources, client);
|
||||||
|
toplevel_send_details_to_toplevel_resource(toplevel,
|
||||||
|
toplevel_resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *manager =
|
||||||
|
wl_container_of(listener, manager, display_destroy);
|
||||||
|
wl_signal_emit_mutable(&manager->events.destroy, manager);
|
||||||
|
wl_list_remove(&manager->display_destroy.link);
|
||||||
|
wl_global_destroy(manager->global);
|
||||||
|
free(manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *wlr_foreign_toplevel_manager_v1_create(
|
||||||
|
struct wl_display *display) {
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *manager = calloc(1,
|
||||||
|
sizeof(struct wlr_foreign_toplevel_manager_v1));
|
||||||
|
if (!manager) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager->event_loop = wl_display_get_event_loop(display);
|
||||||
|
manager->global = wl_global_create(display,
|
||||||
|
&zwlr_foreign_toplevel_manager_v1_interface,
|
||||||
|
FOREIGN_TOPLEVEL_MANAGEMENT_V1_VERSION, manager,
|
||||||
|
foreign_toplevel_manager_bind);
|
||||||
|
if (!manager->global) {
|
||||||
|
free(manager);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_signal_init(&manager->events.destroy);
|
||||||
|
wl_list_init(&manager->resources);
|
||||||
|
wl_list_init(&manager->toplevels);
|
||||||
|
|
||||||
|
manager->display_destroy.notify = handle_display_destroy;
|
||||||
|
wl_display_add_destroy_listener(display, &manager->display_destroy);
|
||||||
|
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
153
wlr_foreign_toplevel_management_v1.h
Executable file
153
wlr_foreign_toplevel_management_v1.h
Executable file
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||||
|
* future consistency of this API.
|
||||||
|
*/
|
||||||
|
#ifndef WLR_USE_UNSTABLE
|
||||||
|
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLR_TYPES_WLR_FOREIGN_TOPLEVEL_MANAGEMENT_V1_H
|
||||||
|
#define WLR_TYPES_WLR_FOREIGN_TOPLEVEL_MANAGEMENT_V1_H
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/types/wlr_output.h>
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 {
|
||||||
|
struct wl_event_loop *event_loop;
|
||||||
|
struct wl_global *global;
|
||||||
|
struct wl_list resources; // wl_resource_get_link()
|
||||||
|
struct wl_list toplevels; // wlr_foreign_toplevel_handle_v1.link
|
||||||
|
|
||||||
|
struct wl_listener display_destroy;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_signal destroy;
|
||||||
|
} events;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wlr_foreign_toplevel_handle_v1_state {
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED = (1 << 0),
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED = (1 << 1),
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED = (1 << 2),
|
||||||
|
WLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN = (1 << 3),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_output {
|
||||||
|
struct wl_list link; // wlr_foreign_toplevel_handle_v1.outputs
|
||||||
|
struct wlr_output *output;
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
|
||||||
|
// private state
|
||||||
|
|
||||||
|
struct wl_listener output_bind;
|
||||||
|
struct wl_listener output_destroy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 {
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *manager;
|
||||||
|
struct wl_list resources;
|
||||||
|
struct wl_list link;
|
||||||
|
struct wl_event_source *idle_source;
|
||||||
|
|
||||||
|
char *title;
|
||||||
|
char *app_id;
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *parent;
|
||||||
|
struct wl_list outputs; // wlr_foreign_toplevel_v1_output.link
|
||||||
|
uint32_t state; // enum wlr_foreign_toplevel_v1_state
|
||||||
|
|
||||||
|
struct {
|
||||||
|
// struct wlr_foreign_toplevel_handle_v1_maximized_event
|
||||||
|
struct wl_signal request_maximize;
|
||||||
|
// struct wlr_foreign_toplevel_handle_v1_minimized_event
|
||||||
|
struct wl_signal request_minimize;
|
||||||
|
// struct wlr_foreign_toplevel_handle_v1_activated_event
|
||||||
|
struct wl_signal request_activate;
|
||||||
|
// struct wlr_foreign_toplevel_handle_v1_fullscreen_event
|
||||||
|
struct wl_signal request_fullscreen;
|
||||||
|
struct wl_signal request_close;
|
||||||
|
|
||||||
|
// struct wlr_foreign_toplevel_handle_v1_set_rectangle_event
|
||||||
|
struct wl_signal set_rectangle;
|
||||||
|
struct wl_signal destroy;
|
||||||
|
} events;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_maximized_event {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
bool maximized;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_minimized_event {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
bool minimized;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_activated_event {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
struct wlr_seat *seat;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_fullscreen_event {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
bool fullscreen;
|
||||||
|
struct wlr_output *output;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1_set_rectangle_event {
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel;
|
||||||
|
struct wlr_surface *surface;
|
||||||
|
int32_t x, y, width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *wlr_foreign_toplevel_manager_v1_create(
|
||||||
|
struct wl_display *display);
|
||||||
|
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *wlr_foreign_toplevel_handle_v1_create(
|
||||||
|
struct wlr_foreign_toplevel_manager_v1 *manager);
|
||||||
|
/**
|
||||||
|
* Destroy the given toplevel handle, sending the closed event to any
|
||||||
|
* client. Also, if the destroyed toplevel is set as a parent of any
|
||||||
|
* other valid toplevel, clients still holding a handle to both are
|
||||||
|
* sent a parent signal with NULL parent. If this is not desired, the
|
||||||
|
* caller should ensure that any child toplevels are destroyed before
|
||||||
|
* the parent.
|
||||||
|
*/
|
||||||
|
void wlr_foreign_toplevel_handle_v1_destroy(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel);
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_title(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, const char *title);
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_app_id(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, const char *app_id);
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_output_enter(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, struct wlr_output *output);
|
||||||
|
void wlr_foreign_toplevel_handle_v1_output_leave(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, struct wlr_output *output);
|
||||||
|
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_maximized(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, bool maximized);
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_minimized(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, bool minimized);
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_activated(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel, bool activated);
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_fullscreen(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1* toplevel, bool fullscreen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parent of a toplevel. If the parent changed from its previous
|
||||||
|
* value, also sends a parent event to all clients that hold handles to
|
||||||
|
* both toplevel and parent (no message is sent to clients that have
|
||||||
|
* previously destroyed their parent handle). NULL is allowed as the
|
||||||
|
* parent, meaning no parent exists.
|
||||||
|
*/
|
||||||
|
void wlr_foreign_toplevel_handle_v1_set_parent(
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *toplevel,
|
||||||
|
struct wlr_foreign_toplevel_handle_v1 *parent);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue