i mean, there are too many changes to even comment it
This commit is contained in:
+177
-17
@@ -1,23 +1,183 @@
|
|||||||
BasedOnStyle: LLVM
|
|
||||||
Language: C
|
# FreeBSD .clang-format
|
||||||
|
|
||||||
|
---
|
||||||
|
BasedOnStyle: WebKit
|
||||||
|
AlignAfterOpenBracket: DontAlign
|
||||||
|
AlignConsecutiveMacros: AcrossEmptyLines
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: false
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: WebKit
|
||||||
|
BreakBeforeTernaryOperators: false
|
||||||
|
BreakStringLiterals: false
|
||||||
|
PenaltyBreakAssignment: 100
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 100
|
||||||
|
CompactNamespaces: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ForEachMacros:
|
||||||
|
- ARB_ARRFOREACH
|
||||||
|
- ARB_ARRFOREACH_REVWCOND
|
||||||
|
- ARB_ARRFOREACH_REVERSE
|
||||||
|
- ARB_FOREACH
|
||||||
|
- ARB_FOREACH_FROM
|
||||||
|
- ARB_FOREACH_SAFE
|
||||||
|
- ARB_FOREACH_REVERSE
|
||||||
|
- ARB_FOREACH_REVERSE_FROM
|
||||||
|
- ARB_FOREACH_REVERSE_SAFE
|
||||||
|
- BIT_FOREACH_ISCLR
|
||||||
|
- BIT_FOREACH_ISSET
|
||||||
|
- CPU_FOREACH
|
||||||
|
- CPU_FOREACH_ISCLR
|
||||||
|
- CPU_FOREACH_ISSET
|
||||||
|
- FOREACH_THREAD_IN_PROC
|
||||||
|
- FOREACH_PROC_IN_SYSTEM
|
||||||
|
- FOREACH_PRISON_CHILD
|
||||||
|
- FOREACH_PRISON_DESCENDANT
|
||||||
|
- FOREACH_PRISON_DESCENDANT_LOCKED
|
||||||
|
- FOREACH_PRISON_DESCENDANT_LOCKED_LEVEL
|
||||||
|
- MNT_VNODE_FOREACH_ALL
|
||||||
|
- MNT_VNODE_FOREACH_ACTIVE
|
||||||
|
- RB_FOREACH
|
||||||
|
- RB_FOREACH_FROM
|
||||||
|
- RB_FOREACH_SAFE
|
||||||
|
- RB_FOREACH_REVERSE
|
||||||
|
- RB_FOREACH_REVERSE_FROM
|
||||||
|
- RB_FOREACH_REVERSE_SAFE
|
||||||
|
- SLIST_FOREACH
|
||||||
|
- SLIST_FOREACH_FROM
|
||||||
|
- SLIST_FOREACH_FROM_SAFE
|
||||||
|
- SLIST_FOREACH_SAFE
|
||||||
|
- SLIST_FOREACH_PREVPTR
|
||||||
|
- SPLAY_FOREACH
|
||||||
|
- LIST_FOREACH
|
||||||
|
- LIST_FOREACH_FROM
|
||||||
|
- LIST_FOREACH_FROM_SAFE
|
||||||
|
- LIST_FOREACH_SAFE
|
||||||
|
- STAILQ_FOREACH
|
||||||
|
- STAILQ_FOREACH_FROM
|
||||||
|
- STAILQ_FOREACH_FROM_SAFE
|
||||||
|
- STAILQ_FOREACH_SAFE
|
||||||
|
- TAILQ_FOREACH
|
||||||
|
- TAILQ_FOREACH_FROM
|
||||||
|
- TAILQ_FOREACH_FROM_SAFE
|
||||||
|
- TAILQ_FOREACH_REVERSE
|
||||||
|
- TAILQ_FOREACH_REVERSE_FROM
|
||||||
|
- TAILQ_FOREACH_REVERSE_FROM_SAFE
|
||||||
|
- TAILQ_FOREACH_REVERSE_SAFE
|
||||||
|
- TAILQ_FOREACH_SAFE
|
||||||
|
- VM_MAP_ENTRY_FOREACH
|
||||||
|
- VM_PAGE_DUMP_FOREACH
|
||||||
|
SpaceBeforeParens: ControlStatementsExceptForEachMacros
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
Language: Cpp
|
||||||
|
NamespaceIndentation: None
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
IndentWidth: 8
|
IndentWidth: 8
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
ColumnLimit: 120
|
ColumnLimit: 80
|
||||||
UseTab: Always
|
UseTab: Always
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^\"opt_.*\.h\"'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 10
|
||||||
|
- Regex: '^<sys/cdefs\.h>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 20
|
||||||
|
- Regex: '^<sys/types\.h>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 21
|
||||||
|
- Regex: '^<sys/param\.h>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 22
|
||||||
|
- Regex: '^<sys/systm\.h>'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 23
|
||||||
|
- Regex: '^<sys.*/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 24
|
||||||
|
- Regex: '^<vm/vm\.h>'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 30
|
||||||
|
- Regex: '^<vm/'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 31
|
||||||
|
- Regex: '^<machine/'
|
||||||
|
Priority: 4
|
||||||
|
SortPriority: 40
|
||||||
|
- Regex: '^<(x86|amd64|i386|xen)/'
|
||||||
|
Priority: 5
|
||||||
|
SortPriority: 50
|
||||||
|
- Regex: '^<dev/'
|
||||||
|
Priority: 6
|
||||||
|
SortPriority: 60
|
||||||
|
- Regex: '^<net.*/'
|
||||||
|
Priority: 7
|
||||||
|
SortPriority: 70
|
||||||
|
- Regex: '^<protocols/'
|
||||||
|
Priority: 7
|
||||||
|
SortPriority: 71
|
||||||
|
- Regex: '^<(fs|nfs(|client|server)|ufs)/'
|
||||||
|
Priority: 8
|
||||||
|
SortPriority: 80
|
||||||
|
- Regex: '^<[^/].*'
|
||||||
|
Priority: 9
|
||||||
|
SortPriority: 90
|
||||||
|
- Regex: '^\".*\"'
|
||||||
|
Priority: 10
|
||||||
|
SortPriority: 100
|
||||||
|
IncludeIsMainRegex: 'BLAH_DONT_MATCH_ANYTHING'
|
||||||
SortIncludes: true
|
SortIncludes: true
|
||||||
BraceWrapping:
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
AfterClass: false
|
TypenameMacros:
|
||||||
AfterControlStatement: false
|
- ARB_ELMTYPE
|
||||||
AfterEnum: false
|
- ARB_HEAD
|
||||||
AfterFunction: true
|
- ARB8_HEAD
|
||||||
AfterNamespace: false
|
- ARB16_HEAD
|
||||||
AfterObjCDeclaration: false
|
- ARB32_HEAD
|
||||||
AfterStruct: false
|
- ARB_ENTRY
|
||||||
AfterUnion: false
|
- ARB8_ENTRY
|
||||||
BeforeCatch: false
|
- ARB16_ENTRY
|
||||||
BeforeElse: false
|
- ARB32_ENTRY
|
||||||
IndentBraces: false
|
- LIST_CLASS_ENTRY
|
||||||
BreakBeforeBraces: Custom
|
- LIST_CLASS_HEAD
|
||||||
|
- LIST_ENTRY
|
||||||
|
- LIST_HEAD
|
||||||
|
- QUEUE_TYPEOF
|
||||||
|
- RB_ENTRY
|
||||||
|
- RB_HEAD
|
||||||
|
- SLIST_CLASS_HEAD
|
||||||
|
- SLIST_CLASS_ENTRY
|
||||||
|
- SLIST_HEAD
|
||||||
|
- SLIST_ENTRY
|
||||||
|
- SMR_POINTER
|
||||||
|
- SPLAY_ENTRY
|
||||||
|
- SPLAY_HEAD
|
||||||
|
- STAILQ_CLASS_ENTRY
|
||||||
|
- STAILQ_CLASS_HEAD
|
||||||
|
- STAILQ_ENTRY
|
||||||
|
- STAILQ_HEAD
|
||||||
|
- TAILQ_CLASS_ENTRY
|
||||||
|
- TAILQ_CLASS_HEAD
|
||||||
|
- TAILQ_ENTRY
|
||||||
|
- TAILQ_HEAD
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
absinthe
|
absinthe
|
||||||
xdg-shell-protocol.h
|
xdg-shell-protocol.h
|
||||||
|
wlr-layer-shell-unstable-v1-protocol.h
|
||||||
tags
|
tags
|
||||||
|
compile_commands.json
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ all: compile
|
|||||||
|
|
||||||
proto:
|
proto:
|
||||||
wayland-scanner server-header $(shell pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.h
|
wayland-scanner server-header $(shell pkg-config --variable=pkgdatadir wayland-protocols)/stable/xdg-shell/xdg-shell.xml xdg-shell-protocol.h
|
||||||
|
wayland-scanner server-header ./protocols/wlr-layer-shell-unstable-v1.xml wlr-layer-shell-unstable-v1-protocol.h
|
||||||
|
|
||||||
compile: proto
|
compile: proto
|
||||||
gcc -o absinthe src/* \
|
gcc -o absinthe src/* \
|
||||||
-Wall -Wextra \
|
-Wall -Wextra -Wpedantic \
|
||||||
-DXWAYLAND \
|
|
||||||
-I./ -I./include -DWLR_USE_UNSTABLE $(shell pkg-config wlroots-0.20 --libs --cflags) -lwayland-server -lxkbcommon \
|
-I./ -I./include -DWLR_USE_UNSTABLE $(shell pkg-config wlroots-0.20 --libs --cflags) -lwayland-server -lxkbcommon \
|
||||||
-O3 \
|
-O3 \
|
||||||
-g
|
-g
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
void absinthe_toplevel_map(struct wl_listener *listener, void *data);
|
|
||||||
void absinthe_toplevel_unmap(struct wl_listener *listener, void *data);
|
|
||||||
void absinthe_toplevel_destroy(struct wl_listener *listener, void *data);
|
|
||||||
void absinthe_toplevel_request_move(struct wl_listener *listener, void *data);
|
|
||||||
void absinthe_toplevel_request_resize(struct wl_listener *listener, void *data);
|
|
||||||
void absinthe_toplevel_request_maximize(struct wl_listener *listener, void *data);
|
|
||||||
void absinthe_toplevel_request_fullscreen(struct wl_listener *listener, void *data);
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, double lx, double ly,
|
|
||||||
struct wlr_surface **surface, double *sx, double *sy);
|
|
||||||
|
|
||||||
bool absinthe_toplevel_is_unmanaged(struct absinthe_toplevel *toplevel);
|
|
||||||
|
|
||||||
void absinthe_toplevel_update_geometry(struct absinthe_toplevel *toplevel);
|
|
||||||
void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel);
|
|
||||||
|
|
||||||
void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t x, int32_t y);
|
|
||||||
void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height);
|
|
||||||
void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen);
|
|
||||||
void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4]);
|
|
||||||
+14
-12
@@ -1,17 +1,19 @@
|
|||||||
#pragma once
|
#ifndef __CONFIG_H_
|
||||||
|
#define __CONFIG_H_
|
||||||
|
|
||||||
#define ABSINTHE_CURSOR_MOD WLR_MODIFIER_ALT
|
#define CURSOR_MOD WLR_MODIFIER_ALT
|
||||||
#define ABSINTHE_CURSOR_MOVE_BUTTON BTN_LEFT
|
#define CURSOR_MOVE_BUTTON BTN_LEFT
|
||||||
#define ABSINTHE_CURSOR_RESIZE_BUTTON BTN_RIGHT
|
#define CURSOR_RESIZE_BUTTON BTN_RIGHT
|
||||||
|
|
||||||
#define ABSINTHE_TOPLEVEL_BORDER_WIDTH 1
|
#define TOPLEVEL_BW 1
|
||||||
|
|
||||||
static const float focused_border_color[4] = {0.64, 0.75, 0.55, 1.0};
|
static const float focused_bc[4] = { 0.64, 0.75, 0.55, 1.0 };
|
||||||
static const float urgent_border_color[4] = {0.84, 0.47, 0.5, 1.0};
|
static const float urgent_bc[4] = { 0.84, 0.47, 0.5, 1.0 };
|
||||||
static const float unfocused_border_color[4] = {0.39, 0.42, 0.46, 1.0};
|
static const float unfocused_bc[4] = { 0.39, 0.42, 0.46, 1.0 };
|
||||||
|
|
||||||
#define ABSINTHE_MAIN_STACK_SIZE 1;
|
#define MSTACK_SIZE 1
|
||||||
#define ABSINTHE_MAIN_STACK_WIDTH 0.5;
|
#define MSTACK_WIDTH 0.5
|
||||||
|
|
||||||
#define ABSINTHE_OUTPUT_GAP 0
|
#define OUTPUT_GAP 0
|
||||||
#define ABSINTHE_LAYOUT_GAP 0
|
#define LAYOUT_GAP 0
|
||||||
|
#endif
|
||||||
|
|||||||
+4
-1
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#ifndef __FOCUS_H_
|
||||||
|
#define __FOCUS_H_
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
@@ -8,3 +9,5 @@ struct absinthe_toplevel *focus_get_topmost(struct absinthe_server *server);
|
|||||||
|
|
||||||
void focus_next(struct absinthe_server *server);
|
void focus_next(struct absinthe_server *server);
|
||||||
void focus_prev(struct absinthe_server *server);
|
void focus_prev(struct absinthe_server *server);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
#pragma once
|
#ifndef __KEYBINDS_CALLBACKS_H
|
||||||
|
#define __KEYBINDS_CALLBACKS_H
|
||||||
|
|
||||||
void run_command();
|
#endif
|
||||||
|
|||||||
+7
-4
@@ -1,7 +1,10 @@
|
|||||||
#pragma once
|
#ifndef __KEYBOARD_H_
|
||||||
|
#define __KEYBOARD_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void keyboard_handle_modifiers(struct wl_listener *listener, void *data);
|
void handle_modifiers(struct wl_listener *listener, void *data);
|
||||||
void keyboard_handle_key(struct wl_listener *listener, void *data);
|
void handle_key(struct wl_listener *listener, void *data);
|
||||||
void keyboard_handle_destroy(struct wl_listener *listener, void *data);
|
void handle_destroy(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __LAYER_SURFACE_H_
|
||||||
|
#define __LAYER_SURFACE_H_
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
|
void layer_surface_map(struct wl_listener *listener, void *data);
|
||||||
|
void layer_surface_unmap(struct wl_listener *listener, void *data);
|
||||||
|
void layer_surface_commit(struct wl_listener *listener, void *data);
|
||||||
|
void layer_surface_destroy(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
+4
-1
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#ifndef __LAYOUT_H_
|
||||||
|
#define __LAYOUT_H_
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void layout_arrange(struct absinthe_output *output);
|
void layout_arrange(struct absinthe_output *output);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+5
-2
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#ifndef __OUTPUT_H_
|
||||||
|
#define __OUTPUT_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
@@ -7,6 +8,8 @@
|
|||||||
void output_frame(struct wl_listener *listener, void *data);
|
void output_frame(struct wl_listener *listener, void *data);
|
||||||
void output_request_state(struct wl_listener *listener, void *data);
|
void output_request_state(struct wl_listener *listener, void *data);
|
||||||
void output_destroy(struct wl_listener *listener, void *data);
|
void output_destroy(struct wl_listener *listener, void *data);
|
||||||
void outputs_update(struct wl_listener *listener, void *data);
|
void output_layout_change(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void update_focused_output(struct absinthe_server *server);
|
void update_focused_output(struct absinthe_server *server);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+7
-4
@@ -1,7 +1,10 @@
|
|||||||
#pragma once
|
#ifndef __SEAT_H_
|
||||||
|
#define __SEAT_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void seat_request_cursor(struct wl_listener *listener, void *data);
|
void request_cursor(struct wl_listener *listener, void *data);
|
||||||
void seat_pointer_focus_change(struct wl_listener *listener, void *data);
|
void pointer_focus_change(struct wl_listener *listener, void *data);
|
||||||
void seat_request_set_selection(struct wl_listener *listener, void *data);
|
void request_set_selection(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+18
-13
@@ -1,22 +1,27 @@
|
|||||||
#pragma once
|
#ifndef __SERVER_H_
|
||||||
|
#define __SERVER_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void server_new_output(struct wl_listener *listener, void *data);
|
void new_output(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void server_new_xdg_toplevel(struct wl_listener *listener, void *data);
|
void new_xdg_toplevel(struct wl_listener *listener, void *data);
|
||||||
void server_new_xdg_popup(struct wl_listener *listener, void *data);
|
void new_xdg_popup(struct wl_listener *listener, void *data);
|
||||||
void server_new_xdg_decoration(struct wl_listener *listener, void *data);
|
void new_xdg_decoration(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
void new_layer_surface(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
void server_xwayland_ready(struct wl_listener *listener, void *data);
|
void xwayland_ready(struct wl_listener *listener, void *data);
|
||||||
void server_xwayland_new_surface(struct wl_listener *listener, void *data);
|
void xwayland_new_surface(struct wl_listener *listener, void *data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void server_cursor_motion(struct wl_listener *listener, void *data);
|
void cursor_motion(struct wl_listener *listener, void *data);
|
||||||
void server_cursor_motion_absolute(struct wl_listener *listener, void *data);
|
void cursor_motion_abs(struct wl_listener *listener, void *data);
|
||||||
void server_cursor_button(struct wl_listener *listener, void *data);
|
void cursor_button(struct wl_listener *listener, void *data);
|
||||||
void server_cursor_axis(struct wl_listener *listener, void *data);
|
void cursor_axis(struct wl_listener *listener, void *data);
|
||||||
void server_cursor_frame(struct wl_listener *listener, void *data);
|
void cursor_frame(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
void server_new_input(struct wl_listener *listener, void *data);
|
void new_input(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef __TOPLEVLE_HANDLERS_H_
|
||||||
|
#define __TOPLEVLE_HANDLERS_H_
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
|
void toplevel_map(struct wl_listener *listener, void *data);
|
||||||
|
void toplevel_unmap(struct wl_listener *listener, void *data);
|
||||||
|
void toplevel_destroy(struct wl_listener *listener, void *data);
|
||||||
|
void toplevel_request_move(struct wl_listener *listener, void *data);
|
||||||
|
void toplevel_request_resize(struct wl_listener *listener, void *data);
|
||||||
|
void toplevel_request_maximize(struct wl_listener *listener, void *data);
|
||||||
|
void toplevel_request_fullscreen(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __TOPLEVEL_H_
|
||||||
|
#define __TOPLEVEL_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
struct absinthe_toplevel *toplevel_at(struct absinthe_server *server, double lx,
|
||||||
|
double ly, struct wlr_surface **surface, double *sx, double *sy);
|
||||||
|
|
||||||
|
bool toplevel_is_unmanaged(struct absinthe_toplevel *toplevel);
|
||||||
|
|
||||||
|
void toplevel_update_geom(struct absinthe_toplevel *toplevel);
|
||||||
|
void toplevel_update_borders_geom(struct absinthe_toplevel *toplevel);
|
||||||
|
|
||||||
|
void toplevel_set_pos(struct absinthe_toplevel *toplevel, int32_t x, int32_t y);
|
||||||
|
void toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width,
|
||||||
|
int32_t height);
|
||||||
|
void toplevel_set_fullscreen(struct absinthe_toplevel *toplevel,
|
||||||
|
bool fullscreen);
|
||||||
|
void toplevel_set_border_color(struct absinthe_toplevel *toplevel,
|
||||||
|
const float color[4]);
|
||||||
|
|
||||||
|
#endif
|
||||||
+87
-57
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#ifndef __TYPES_H_
|
||||||
|
#define __TYPES_H_
|
||||||
|
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
@@ -21,39 +22,43 @@
|
|||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
#define MAX(A, B) (A) > (B) ? (A) : (B)
|
||||||
|
#define MIN(A, B) (A) < (B) ? (A) : (B)
|
||||||
|
#define LISTEN(L, C, E) \
|
||||||
|
do { \
|
||||||
|
(L).notify = (C); \
|
||||||
|
wl_signal_add(&(E), &(L)); \
|
||||||
|
} while (0);
|
||||||
|
#define UNUSED(X) (void)(X)
|
||||||
|
|
||||||
#define UNUSED(x) (void)(x)
|
enum {
|
||||||
|
CURSOR_PASSTHROUGH,
|
||||||
enum absinthe_cursor_mode {
|
CURSOR_MOVE,
|
||||||
ABSINTHE_CURSOR_PASSTHROUGH,
|
CURSOR_RESIZE,
|
||||||
ABSINTHE_CURSOR_MOVE,
|
|
||||||
ABSINTHE_CURSOR_RESIZE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum absinthe_cursor_resize_corner {
|
enum {
|
||||||
ABSINTHE_CURSOR_RESIZE_CORNER_TOP_LEFT,
|
TOP_LEFT,
|
||||||
ABSINTHE_CURSOR_RESIZE_CORNER_TOP_RIGHT,
|
TOP_RIGHT,
|
||||||
ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_LEFT,
|
BOTTOM_LEFT,
|
||||||
ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_RIGHT,
|
BOTTOM_RIGHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum absinthe_toplevel_type {
|
enum {
|
||||||
ABSINTHE_TOPLEVEL_XDG,
|
TOPLEVEL_XDG,
|
||||||
ABSINTHE_TOPLEVEL_LAYER_SHELL,
|
TOPLEVEL_X11,
|
||||||
ABSINTHE_TOPLEVEL_X11,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum absinthe_layers {
|
enum absinthe_layers {
|
||||||
ABSINTHE_LAYER_BACKGROUND,
|
LAYER_BACKGROUND,
|
||||||
ABSINTHE_LAYER_BOTTOM,
|
LAYER_BOTTOM,
|
||||||
ABSINTHE_LAYER_TILE,
|
LAYER_TILE,
|
||||||
ABSINTHE_LAYER_FLOAT,
|
LAYER_FLOAT,
|
||||||
ABSINTHE_LAYER_TOP,
|
LAYER_TOP,
|
||||||
ABSINTHE_LAYER_FULLSCREEN,
|
LAYER_FULLSCREEN,
|
||||||
ABSINTHE_LAYER_OVERLAY,
|
LAYER_OVERLAY,
|
||||||
ABSINTHE_LAYER_LOCK,
|
LAYER_LOCK,
|
||||||
ABSINTHE_LAYERS_COUNT,
|
LAYERS_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct absinthe_output;
|
struct absinthe_output;
|
||||||
@@ -70,19 +75,23 @@ struct absinthe_server {
|
|||||||
struct wlr_xdg_shell *xdg_shell;
|
struct wlr_xdg_shell *xdg_shell;
|
||||||
struct wl_listener new_xdg_toplevel;
|
struct wl_listener new_xdg_toplevel;
|
||||||
struct wl_listener new_xdg_popup;
|
struct wl_listener new_xdg_popup;
|
||||||
struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
|
struct wlr_xdg_decoration_manager_v1 *xdg_deco_mgr;
|
||||||
struct wl_listener new_xdg_decoration;
|
struct wl_listener new_xdg_deco;
|
||||||
|
|
||||||
|
struct wlr_layer_shell *layer_shell;
|
||||||
|
struct wl_listener new_layer_surface;
|
||||||
|
struct wlr_scene_tree *layers[LAYERS_COUNT];
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
struct wlr_xwayland *xwayland;
|
struct wlr_xwayland *xwayland;
|
||||||
struct wl_listener xwayland_new_surface;
|
struct wl_listener xw_new_surface;
|
||||||
struct wl_listener xwayland_ready;
|
struct wl_listener xw_ready;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct wlr_xcursor_manager *cursor_mgr;
|
struct wlr_xcursor_manager *cursor_mgr;
|
||||||
struct wl_listener cursor_motion;
|
struct wl_listener cursor_motion;
|
||||||
struct wl_listener cursor_motion_absolute;
|
struct wl_listener cursor_motion_abs;
|
||||||
struct wl_listener cursor_button;
|
struct wl_listener cursor_button;
|
||||||
struct wl_listener cursor_axis;
|
struct wl_listener cursor_axis;
|
||||||
struct wl_listener cursor_frame;
|
struct wl_listener cursor_frame;
|
||||||
@@ -94,10 +103,10 @@ struct absinthe_server {
|
|||||||
struct wl_listener request_set_selection;
|
struct wl_listener request_set_selection;
|
||||||
struct wl_list keyboards;
|
struct wl_list keyboards;
|
||||||
|
|
||||||
enum absinthe_cursor_mode cursor_mode;
|
int cursor_mode;
|
||||||
struct wlr_box grabbed_geometry;
|
int resize_corner;
|
||||||
|
struct wlr_box grab_geom;
|
||||||
int32_t grab_x, grab_y;
|
int32_t grab_x, grab_y;
|
||||||
enum absinthe_cursor_resize_corner cursor_resize_corner;
|
|
||||||
|
|
||||||
struct wl_list toplevels;
|
struct wl_list toplevels;
|
||||||
struct wl_list focus_stack;
|
struct wl_list focus_stack;
|
||||||
@@ -107,49 +116,68 @@ struct absinthe_server {
|
|||||||
struct wl_list outputs;
|
struct wl_list outputs;
|
||||||
struct wl_listener new_output;
|
struct wl_listener new_output;
|
||||||
struct wlr_output_layout *output_layout;
|
struct wlr_output_layout *output_layout;
|
||||||
struct wl_listener output_layout_change;
|
struct wl_listener layout_change;
|
||||||
struct wlr_output_manager_v1 *output_mgr;
|
struct wlr_output_manager_v1 *output_mgr;
|
||||||
struct wl_listener output_mgr_apply;
|
struct wl_listener mgr_apply;
|
||||||
struct wl_listener output_mgr_test;
|
struct wl_listener mgr_test;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct absinthe_output {
|
struct absinthe_output {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct absinthe_server *server;
|
struct absinthe_server *server;
|
||||||
struct wlr_box geometry;
|
|
||||||
struct wlr_output *wlr_output;
|
struct wlr_box geom;
|
||||||
|
struct wlr_box usable_area;
|
||||||
|
|
||||||
|
struct wlr_output *wlr;
|
||||||
struct wl_listener frame;
|
struct wl_listener frame;
|
||||||
struct wl_listener request_state;
|
struct wl_listener request_state;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
|
||||||
float main_stack_width;
|
float mstack_width;
|
||||||
float main_stack_size;
|
float mstack_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct absinthe_layer_surface {
|
||||||
|
struct absinthe_server *server;
|
||||||
|
struct absinthe_output *output;
|
||||||
|
|
||||||
|
struct wlr_scene_tree *scene_tree;
|
||||||
|
struct wlr_scene_tree *scene_layer;
|
||||||
|
struct wlr_scene_tree *popups;
|
||||||
|
|
||||||
|
struct wlr_layer_surface_v1 *wlr;
|
||||||
|
struct wl_listener map;
|
||||||
|
struct wl_listener unmap;
|
||||||
|
struct wl_listener commit;
|
||||||
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct absinthe_toplevel {
|
struct absinthe_toplevel {
|
||||||
enum absinthe_toplevel_type type;
|
int type;
|
||||||
|
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list flink;
|
struct wl_list flink;
|
||||||
struct absinthe_server *server;
|
struct absinthe_server *server;
|
||||||
struct absinthe_output *output;
|
struct absinthe_output *output;
|
||||||
|
|
||||||
struct wlr_scene_tree *scene_tree;
|
struct wlr_scene_tree *scene_tree;
|
||||||
struct wlr_scene_tree *scene_surface;
|
struct wlr_scene_tree *scene_surface;
|
||||||
|
|
||||||
int32_t border_width;
|
int32_t bw;
|
||||||
struct wlr_scene_rect *border[4];
|
struct wlr_scene_rect *border[4];
|
||||||
struct wlr_xdg_toplevel_decoration_v1 *decoration;
|
struct wlr_xdg_toplevel_decoration_v1 *deco;
|
||||||
|
|
||||||
bool tiled, floating, fullscreen, maximized;
|
bool tiled, floating, fullscreen, maximized;
|
||||||
bool urgent;
|
bool urgent;
|
||||||
uint32_t resizing;
|
uint32_t resizing;
|
||||||
|
|
||||||
struct wlr_box geometry;
|
struct wlr_box geom;
|
||||||
struct wlr_box prev_geometry;
|
struct wlr_box prev_geom;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct wlr_xdg_toplevel *xdg_toplevel;
|
struct wlr_xdg_toplevel *xdg;
|
||||||
struct wlr_xwayland_surface *xwayland_surface;
|
struct wlr_xwayland_surface *xw;
|
||||||
};
|
};
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
@@ -159,20 +187,20 @@ struct absinthe_toplevel {
|
|||||||
struct wl_listener request_resize;
|
struct wl_listener request_resize;
|
||||||
struct wl_listener request_maximize;
|
struct wl_listener request_maximize;
|
||||||
struct wl_listener request_fullscreen;
|
struct wl_listener request_fullscreen;
|
||||||
struct wl_listener decoration_request_mode;
|
struct wl_listener deco_request_mode;
|
||||||
struct wl_listener decoration_destroy;
|
struct wl_listener deco_destroy;
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
struct wl_listener xwayland_activate;
|
struct wl_listener xw_activate;
|
||||||
struct wl_listener xwayland_associate;
|
struct wl_listener xw_associate;
|
||||||
struct wl_listener xwayland_dissociate;
|
struct wl_listener xw_dissociate;
|
||||||
struct wl_listener xwayland_configure;
|
struct wl_listener xw_configure;
|
||||||
struct wl_listener xwayland_set_hints;
|
struct wl_listener xw_set_hints;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct absinthe_popup {
|
struct absinthe_popup {
|
||||||
struct wlr_xdg_popup *xdg_popup;
|
struct wlr_xdg_popup *wlr;
|
||||||
struct wl_listener commit;
|
struct wl_listener commit;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
@@ -180,8 +208,10 @@ struct absinthe_popup {
|
|||||||
struct absinthe_keyboard {
|
struct absinthe_keyboard {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct absinthe_server *server;
|
struct absinthe_server *server;
|
||||||
struct wlr_keyboard *wlr_keyboard;
|
struct wlr_keyboard *wlr;
|
||||||
struct wl_listener modifiers;
|
struct wl_listener modifiers;
|
||||||
struct wl_listener key;
|
struct wl_listener key;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* __TYPES_H_ */
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#ifndef __XDG_DECORATION_H_
|
||||||
|
#define __XDG_DECORATION_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void xdg_decoration_request_mode(struct wl_listener *listener, void *data);
|
void deco_request_mode(struct wl_listener *listener, void *data);
|
||||||
void xdg_decoration_destroy(struct wl_listener *listener, void *data);
|
void deco_destroy(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#ifndef __XDG_POPUP_H_
|
||||||
|
#define __XDG_POPUP_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void xdg_popup_commit(struct wl_listener *listener, void *data);
|
void xdg_popup_commit(struct wl_listener *listener, void *data);
|
||||||
void xdg_popup_destroy(struct wl_listener *listener, void *data);
|
void xdg_popup_destroy(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#ifndef __XDG_TOPLEVEL_H_
|
||||||
|
#define __XDG_TOPLEVEL_H_
|
||||||
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void xdg_toplevel_commit(struct wl_listener *listener, void *data);
|
void toplevel_commit(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
+5
-2
@@ -1,9 +1,12 @@
|
|||||||
#pragma once
|
#ifndef __XWAYLAND_H_
|
||||||
|
#define __XWAYLAND_H_
|
||||||
|
|
||||||
#include <wayland-server.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
void xwayland_activate(struct wl_listener *listener, void *data);
|
void xwayland_activate(struct wl_listener *listener, void *data);
|
||||||
void xwayland_associate(struct wl_listener *listener, void *data);
|
void xwayland_associate(struct wl_listener *listener, void *data);
|
||||||
void xwayland_dissociate(struct wl_listener *listener, void *data);
|
void xwayland_dissociate(struct wl_listener *listener, void *data);
|
||||||
void xwayland_configure(struct wl_listener *listener, void *data);
|
void xwayland_configure(struct wl_listener *listener, void *data);
|
||||||
void xwayland_set_hints(struct wl_listener *listener, void *data);
|
void xwayland_set_hints(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,137 +0,0 @@
|
|||||||
#include <wlr/util/edges.h>
|
|
||||||
|
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "focus.h"
|
|
||||||
#include "layout.h"
|
|
||||||
#include "output.h"
|
|
||||||
|
|
||||||
void absinthe_toplevel_map(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, map);
|
|
||||||
|
|
||||||
toplevel->scene_tree = wlr_scene_tree_create(&toplevel->server->scene->tree);
|
|
||||||
toplevel->scene_tree->node.data = toplevel;
|
|
||||||
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, absinthe_toplevel_is_unmanaged(toplevel));
|
|
||||||
|
|
||||||
toplevel->tiled = true;
|
|
||||||
|
|
||||||
if (toplevel->type != ABSINTHE_TOPLEVEL_X11 &&
|
|
||||||
wl_resource_get_version(toplevel->xdg_toplevel->resource) >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
|
||||||
wlr_xdg_toplevel_set_tiled(toplevel->xdg_toplevel,
|
|
||||||
WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
|
||||||
} else {
|
|
||||||
wlr_xdg_toplevel_set_maximized(toplevel->xdg_toplevel, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH;
|
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (toplevel->type == ABSINTHE_TOPLEVEL_X11) {
|
|
||||||
toplevel->scene_surface =
|
|
||||||
wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->xwayland_surface->surface);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
toplevel->scene_surface =
|
|
||||||
wlr_scene_subsurface_tree_create(toplevel->scene_tree, toplevel->xdg_toplevel->base->surface);
|
|
||||||
}
|
|
||||||
toplevel->scene_surface->node.data = toplevel;
|
|
||||||
|
|
||||||
absinthe_toplevel_update_geometry(toplevel);
|
|
||||||
toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
toplevel->border[i] = wlr_scene_rect_create(toplevel->scene_tree, 0, 0, unfocused_border_color);
|
|
||||||
toplevel->border[i]->node.data = toplevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
update_focused_output(toplevel->server);
|
|
||||||
toplevel->output = toplevel->server->focused_output;
|
|
||||||
toplevel->fullscreen = false;
|
|
||||||
|
|
||||||
wl_list_insert(&toplevel->server->toplevels, &toplevel->link);
|
|
||||||
wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink);
|
|
||||||
|
|
||||||
layout_arrange(toplevel->output);
|
|
||||||
focus_toplevel(focus_get_topmost(toplevel->server));
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_unmap(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, unmap);
|
|
||||||
|
|
||||||
if (toplevel == toplevel->server->focused_toplevel) {
|
|
||||||
toplevel->server->focused_toplevel = NULL;
|
|
||||||
toplevel->server->seat->keyboard_state.focused_surface = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_list_remove(&toplevel->link);
|
|
||||||
wl_list_remove(&toplevel->flink);
|
|
||||||
|
|
||||||
layout_arrange(toplevel->output);
|
|
||||||
focus_toplevel(focus_get_topmost(toplevel->server));
|
|
||||||
|
|
||||||
wlr_scene_node_destroy(&toplevel->scene_tree->node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_destroy(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, destroy);
|
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (toplevel->type == ABSINTHE_TOPLEVEL_X11) {
|
|
||||||
wl_list_remove(&toplevel->xwayland_activate.link);
|
|
||||||
wl_list_remove(&toplevel->xwayland_associate.link);
|
|
||||||
wl_list_remove(&toplevel->xwayland_dissociate.link);
|
|
||||||
wl_list_remove(&toplevel->xwayland_configure.link);
|
|
||||||
wl_list_remove(&toplevel->xwayland_set_hints.link);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
wl_list_remove(&toplevel->map.link);
|
|
||||||
wl_list_remove(&toplevel->unmap.link);
|
|
||||||
wl_list_remove(&toplevel->commit.link);
|
|
||||||
wl_list_remove(&toplevel->request_move.link);
|
|
||||||
wl_list_remove(&toplevel->request_resize.link);
|
|
||||||
}
|
|
||||||
|
|
||||||
wl_list_remove(&toplevel->destroy.link);
|
|
||||||
wl_list_remove(&toplevel->request_maximize.link);
|
|
||||||
wl_list_remove(&toplevel->request_fullscreen.link);
|
|
||||||
|
|
||||||
free(toplevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_request_move(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize);
|
|
||||||
if (toplevel->xdg_toplevel->base->initialized)
|
|
||||||
wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_request_resize(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize);
|
|
||||||
if (toplevel->xdg_toplevel->base->initialized)
|
|
||||||
wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_request_maximize(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_maximize);
|
|
||||||
if (toplevel->xdg_toplevel->base->initialized)
|
|
||||||
wlr_xdg_surface_schedule_configure(toplevel->xdg_toplevel->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_request_fullscreen(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
UNUSED(data);
|
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, request_fullscreen);
|
|
||||||
absinthe_toplevel_set_fullscreen(toplevel, toplevel->xdg_toplevel->requested.fullscreen);
|
|
||||||
}
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <wayland-server-core.h>
|
|
||||||
#include <wlr/util/log.h>
|
|
||||||
|
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "focus.h"
|
|
||||||
#include "layout.h"
|
|
||||||
#include "output.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "xdg-shell-protocol.h"
|
|
||||||
|
|
||||||
struct absinthe_toplevel *absinthe_toplevel_at(struct absinthe_server *server, double lx, double ly,
|
|
||||||
struct wlr_surface **surface, double *sx, double *sy)
|
|
||||||
{
|
|
||||||
struct wlr_scene_node *node = wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy);
|
|
||||||
if (!node) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (node->type) {
|
|
||||||
case WLR_SCENE_NODE_BUFFER:
|
|
||||||
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
|
|
||||||
struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer);
|
|
||||||
if (!scene_surface) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*surface = scene_surface->surface;
|
|
||||||
struct wlr_scene_tree *tree = node->parent;
|
|
||||||
while (tree != NULL && tree->node.data == NULL) {
|
|
||||||
tree = tree->node.parent;
|
|
||||||
}
|
|
||||||
return tree->node.data;
|
|
||||||
break;
|
|
||||||
case WLR_SCENE_NODE_RECT:
|
|
||||||
return node->data;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool absinthe_toplevel_is_unmanaged(struct absinthe_toplevel *toplevel)
|
|
||||||
{
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (toplevel->type == ABSINTHE_TOPLEVEL_X11)
|
|
||||||
return toplevel->xwayland_surface->override_redirect;
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_update_geometry(struct absinthe_toplevel *toplevel)
|
|
||||||
{
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (toplevel->type == ABSINTHE_TOPLEVEL_X11) {
|
|
||||||
toplevel->geometry.x = toplevel->xwayland_surface->x;
|
|
||||||
toplevel->geometry.y = toplevel->xwayland_surface->y;
|
|
||||||
toplevel->geometry.width = toplevel->xwayland_surface->width;
|
|
||||||
toplevel->geometry.height = toplevel->xwayland_surface->height;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
toplevel->geometry = toplevel->xdg_toplevel->base->geometry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_update_borders_geometry(struct absinthe_toplevel *toplevel)
|
|
||||||
{
|
|
||||||
int32_t border_width = toplevel->border_width;
|
|
||||||
|
|
||||||
if (toplevel->geometry.width - 2 * border_width < 0 || toplevel->geometry.height - 2 * border_width < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wlr_scene_node_set_position(&toplevel->scene_tree->node, toplevel->geometry.x, toplevel->geometry.y);
|
|
||||||
wlr_scene_node_set_position(&toplevel->scene_surface->node, border_width, border_width);
|
|
||||||
|
|
||||||
wlr_scene_rect_set_size(toplevel->border[0], toplevel->geometry.width - 2 * border_width, border_width);
|
|
||||||
wlr_scene_rect_set_size(toplevel->border[1], toplevel->geometry.width - 2 * border_width, border_width);
|
|
||||||
wlr_scene_rect_set_size(toplevel->border[2], border_width, toplevel->geometry.height);
|
|
||||||
wlr_scene_rect_set_size(toplevel->border[3], border_width, toplevel->geometry.height);
|
|
||||||
|
|
||||||
wlr_scene_node_set_position(&toplevel->border[0]->node, border_width, 0);
|
|
||||||
wlr_scene_node_set_position(&toplevel->border[1]->node, border_width, toplevel->geometry.height - border_width);
|
|
||||||
wlr_scene_node_set_position(&toplevel->border[2]->node, 0, 0);
|
|
||||||
wlr_scene_node_set_position(&toplevel->border[3]->node, toplevel->geometry.width - border_width, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_set_position(struct absinthe_toplevel *toplevel, int32_t x, int32_t y)
|
|
||||||
{
|
|
||||||
toplevel->geometry.x = x;
|
|
||||||
toplevel->geometry.y = y;
|
|
||||||
wlr_scene_node_set_position(&toplevel->scene_tree->node, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width, int32_t height)
|
|
||||||
{
|
|
||||||
if (width <= 2 * toplevel->border_width || height <= 2 * toplevel->border_width ||
|
|
||||||
(width == toplevel->geometry.width && height == toplevel->geometry.height))
|
|
||||||
return;
|
|
||||||
|
|
||||||
toplevel->geometry.width = width;
|
|
||||||
toplevel->geometry.height = height;
|
|
||||||
|
|
||||||
if (toplevel->type == ABSINTHE_TOPLEVEL_XDG) {
|
|
||||||
if (wl_resource_get_version(toplevel->xdg_toplevel->resource) >=
|
|
||||||
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION)
|
|
||||||
wlr_xdg_toplevel_set_bounds(toplevel->xdg_toplevel, width, height);
|
|
||||||
toplevel->resizing = wlr_xdg_toplevel_set_size(
|
|
||||||
toplevel->xdg_toplevel, width - 2 * toplevel->border_width, height - 2 * toplevel->border_width);
|
|
||||||
}
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
else if (toplevel->type == ABSINTHE_TOPLEVEL_X11) {
|
|
||||||
wlr_xwayland_surface_configure(toplevel->xwayland_surface, toplevel->geometry.x, toplevel->geometry.y,
|
|
||||||
width - 2 * toplevel->border_width, height - 2 * toplevel->border_width);
|
|
||||||
absinthe_toplevel_set_position(toplevel, toplevel->geometry.x + toplevel->border_width,
|
|
||||||
toplevel->geometry.y + toplevel->border_width);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct wlr_box clip = {
|
|
||||||
.x = 0,
|
|
||||||
.y = 0,
|
|
||||||
.width = width - toplevel->border_width,
|
|
||||||
.height = height - toplevel->border_width,
|
|
||||||
};
|
|
||||||
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node, &clip);
|
|
||||||
|
|
||||||
absinthe_toplevel_update_borders_geometry(toplevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen)
|
|
||||||
{
|
|
||||||
if (!toplevel || toplevel->fullscreen == fullscreen)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct absinthe_output *output = toplevel->server->focused_output;
|
|
||||||
toplevel->fullscreen = fullscreen;
|
|
||||||
wlr_xdg_toplevel_set_fullscreen(toplevel->xdg_toplevel, fullscreen);
|
|
||||||
|
|
||||||
if (fullscreen) {
|
|
||||||
toplevel->prev_geometry = toplevel->geometry;
|
|
||||||
toplevel->border_width = 0;
|
|
||||||
absinthe_toplevel_set_size(toplevel, output->geometry.width, output->geometry.height);
|
|
||||||
absinthe_toplevel_set_position(toplevel, output->geometry.x, output->geometry.y);
|
|
||||||
} else {
|
|
||||||
toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH;
|
|
||||||
absinthe_toplevel_set_size(toplevel, toplevel->prev_geometry.width, toplevel->prev_geometry.height);
|
|
||||||
absinthe_toplevel_set_position(toplevel, toplevel->prev_geometry.x, toplevel->prev_geometry.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
absinthe_toplevel_update_borders_geometry(toplevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void absinthe_toplevel_set_border_color(struct absinthe_toplevel *toplevel, const float color[4])
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
wlr_scene_rect_set_color(toplevel->border[i], color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+225
@@ -0,0 +1,225 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
||||||
|
#include <wlr/types/wlr_data_control_v1.h>
|
||||||
|
#include <wlr/types/wlr_data_device.h>
|
||||||
|
#include <wlr/types/wlr_drm.h>
|
||||||
|
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||||
|
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
|
||||||
|
#include <wlr/types/wlr_fractional_scale_v1.h>
|
||||||
|
#include <wlr/types/wlr_output_management_v1.h>
|
||||||
|
#include <wlr/types/wlr_presentation_time.h>
|
||||||
|
#include <wlr/types/wlr_screencopy_v1.h>
|
||||||
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
|
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
||||||
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
|
#include <wlr/types/wlr_viewporter.h>
|
||||||
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
|
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "output.h"
|
||||||
|
#include "seat.h"
|
||||||
|
#include "server.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
setup(struct absinthe_server *server)
|
||||||
|
{
|
||||||
|
wlr_log_init(WLR_DEBUG, NULL);
|
||||||
|
server->display = wl_display_create();
|
||||||
|
if (!server->display) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create wl_display");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->backend = wlr_backend_autocreate(wl_display_get_event_loop(
|
||||||
|
server->display),
|
||||||
|
NULL);
|
||||||
|
if (!server->backend) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create wlr_backend");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->renderer = wlr_renderer_autocreate(server->backend);
|
||||||
|
if (!server->renderer) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create wlr_renderer");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_renderer_init_wl_shm(server->renderer, server->display);
|
||||||
|
|
||||||
|
server->scene = wlr_scene_create();
|
||||||
|
if (wlr_renderer_get_texture_formats(server->renderer,
|
||||||
|
WLR_BUFFER_CAP_DMABUF)) {
|
||||||
|
wlr_drm_create(server->display, server->renderer);
|
||||||
|
wlr_scene_set_linux_dmabuf_v1(server->scene,
|
||||||
|
wlr_linux_dmabuf_v1_create_with_renderer(server->display, 5,
|
||||||
|
server->renderer));
|
||||||
|
}
|
||||||
|
|
||||||
|
server->allocator = wlr_allocator_autocreate(server->backend,
|
||||||
|
server->renderer);
|
||||||
|
if (!server->allocator) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create wlr_allocator");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wlroots managers */
|
||||||
|
server->compositor = wlr_compositor_create(server->display, 6,
|
||||||
|
server->renderer);
|
||||||
|
wlr_subcompositor_create(server->display);
|
||||||
|
wlr_data_device_manager_create(server->display);
|
||||||
|
wlr_screencopy_manager_v1_create(server->display);
|
||||||
|
wlr_data_control_manager_v1_create(server->display);
|
||||||
|
wlr_viewporter_create(server->display);
|
||||||
|
wlr_single_pixel_buffer_manager_v1_create(server->display);
|
||||||
|
wlr_fractional_scale_manager_v1_create(server->display, 1);
|
||||||
|
wlr_presentation_create(server->display, server->backend, 2);
|
||||||
|
wlr_alpha_modifier_v1_create(server->display);
|
||||||
|
wlr_export_dmabuf_manager_v1_create(server->display);
|
||||||
|
wlr_ext_foreign_toplevel_list_v1_create(server->display, 1);
|
||||||
|
|
||||||
|
wlr_server_decoration_manager_set_default_mode(
|
||||||
|
wlr_server_decoration_manager_create(server->display),
|
||||||
|
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||||
|
server->xdg_deco_mgr = wlr_xdg_decoration_manager_v1_create(
|
||||||
|
server->display);
|
||||||
|
LISTEN(server->new_xdg_deco, new_xdg_decoration,
|
||||||
|
server->xdg_deco_mgr->events.new_toplevel_decoration);
|
||||||
|
|
||||||
|
/* output */
|
||||||
|
wl_list_init(&server->outputs);
|
||||||
|
LISTEN(server->new_output, new_output,
|
||||||
|
server->backend->events.new_output);
|
||||||
|
|
||||||
|
server->output_layout = wlr_output_layout_create(server->display);
|
||||||
|
LISTEN(server->layout_change, output_layout_change,
|
||||||
|
server->output_layout->events.change);
|
||||||
|
|
||||||
|
server->output_mgr = wlr_output_manager_v1_create(server->display);
|
||||||
|
|
||||||
|
wlr_xdg_output_manager_v1_create(server->display,
|
||||||
|
server->output_layout);
|
||||||
|
|
||||||
|
server->scene_layout = wlr_scene_attach_output_layout(server->scene,
|
||||||
|
server->output_layout);
|
||||||
|
|
||||||
|
/* windows lists */
|
||||||
|
wl_list_init(&server->toplevels);
|
||||||
|
wl_list_init(&server->focus_stack);
|
||||||
|
|
||||||
|
/* xdg_shell */
|
||||||
|
server->xdg_shell = wlr_xdg_shell_create(server->display, 6);
|
||||||
|
LISTEN(server->new_xdg_toplevel, new_xdg_toplevel,
|
||||||
|
server->xdg_shell->events.new_toplevel);
|
||||||
|
LISTEN(server->new_xdg_popup, new_xdg_popup,
|
||||||
|
server->xdg_shell->events.new_popup);
|
||||||
|
|
||||||
|
/* cursor setup */
|
||||||
|
server->cursor = wlr_cursor_create();
|
||||||
|
wlr_cursor_attach_output_layout(server->cursor, server->output_layout);
|
||||||
|
|
||||||
|
server->cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
|
||||||
|
|
||||||
|
server->cursor_mode = CURSOR_PASSTHROUGH;
|
||||||
|
LISTEN(server->cursor_motion, cursor_motion,
|
||||||
|
server->cursor->events.motion);
|
||||||
|
LISTEN(server->cursor_motion_abs, cursor_motion_abs,
|
||||||
|
server->cursor->events.motion_absolute);
|
||||||
|
LISTEN(server->cursor_button, cursor_button,
|
||||||
|
server->cursor->events.button);
|
||||||
|
LISTEN(server->cursor_axis, cursor_axis, server->cursor->events.axis);
|
||||||
|
LISTEN(server->cursor_frame, cursor_frame,
|
||||||
|
server->cursor->events.frame);
|
||||||
|
|
||||||
|
/* keyboard */
|
||||||
|
wl_list_init(&server->keyboards);
|
||||||
|
server->seat = wlr_seat_create(server->display, "seat0");
|
||||||
|
LISTEN(server->new_input, new_input, server->backend->events.new_input);
|
||||||
|
LISTEN(server->request_cursor, request_cursor,
|
||||||
|
server->seat->events.request_set_cursor);
|
||||||
|
LISTEN(server->pointer_focus_change, pointer_focus_change,
|
||||||
|
server->seat->pointer_state.events.focus_change);
|
||||||
|
LISTEN(server->request_set_selection, request_cursor,
|
||||||
|
server->seat->events.request_set_selection);
|
||||||
|
|
||||||
|
unsetenv("DISPLAY");
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if ((server->xwayland = wlr_xwayland_create(server->display,
|
||||||
|
server->compositor, 1))) {
|
||||||
|
LISTEN(server->xw_ready, xwayland_ready,
|
||||||
|
server->xwayland->events.ready);
|
||||||
|
LISTEN(server->xw_new_surface, xwayland_new_surface,
|
||||||
|
server->xwayland->events.new_surface);
|
||||||
|
|
||||||
|
setenv("DISPLAY", server->xwayland->display_name, 1);
|
||||||
|
wlr_log(WLR_INFO, "Running XWayland, DISPLAY=%s",
|
||||||
|
server->xwayland->display_name);
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_ERROR,
|
||||||
|
"Failed to setup XWayland, continuing without it");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *socket = wl_display_add_socket_auto(server->display);
|
||||||
|
if (!socket) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to add socket");
|
||||||
|
wlr_backend_destroy(server->backend);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wlr_backend_start(server->backend)) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to start wlr_backend");
|
||||||
|
wlr_backend_destroy(server->backend);
|
||||||
|
wl_display_destroy(server->display);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setenv("WAYLAND_DISPLAY", socket, true);
|
||||||
|
wlr_log(WLR_INFO, "Running absinthe on WAYLAND_DISPLAY=%s", socket);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(struct absinthe_server *server)
|
||||||
|
{
|
||||||
|
wl_display_destroy_clients(server->display);
|
||||||
|
|
||||||
|
wl_list_remove(&server->new_xdg_toplevel.link);
|
||||||
|
wl_list_remove(&server->new_xdg_popup.link);
|
||||||
|
wl_list_remove(&server->new_xdg_deco.link);
|
||||||
|
|
||||||
|
wl_list_remove(&server->cursor_motion.link);
|
||||||
|
wl_list_remove(&server->cursor_motion_abs.link);
|
||||||
|
wl_list_remove(&server->cursor_button.link);
|
||||||
|
wl_list_remove(&server->cursor_axis.link);
|
||||||
|
wl_list_remove(&server->cursor_frame.link);
|
||||||
|
|
||||||
|
wl_list_remove(&server->new_input.link);
|
||||||
|
wl_list_remove(&server->request_cursor.link);
|
||||||
|
wl_list_remove(&server->pointer_focus_change.link);
|
||||||
|
wl_list_remove(&server->request_set_selection.link);
|
||||||
|
|
||||||
|
wl_list_remove(&server->new_output.link);
|
||||||
|
|
||||||
|
wlr_scene_node_destroy(&server->scene->tree.node);
|
||||||
|
wlr_xcursor_manager_destroy(server->cursor_mgr);
|
||||||
|
wlr_cursor_destroy(server->cursor);
|
||||||
|
wlr_allocator_destroy(server->allocator);
|
||||||
|
wlr_renderer_destroy(server->renderer);
|
||||||
|
wlr_backend_destroy(server->backend);
|
||||||
|
wl_display_destroy(server->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
struct absinthe_server server = { 0 };
|
||||||
|
int error = 0;
|
||||||
|
if ((error = setup(&server)))
|
||||||
|
return error;
|
||||||
|
wl_display_run(server.display);
|
||||||
|
cleanup(&server);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
+48
-40
@@ -1,20 +1,23 @@
|
|||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "toplevel.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void reset_cursor_mode(struct absinthe_server *server)
|
void
|
||||||
|
reset_cursor_mode(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
server->cursor_mode = ABSINTHE_CURSOR_PASSTHROUGH;
|
server->cursor_mode = CURSOR_PASSTHROUGH;
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "default");
|
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "default");
|
||||||
if (server->focused_toplevel) {
|
if (server->focused_toplevel) {
|
||||||
wlr_xdg_toplevel_set_resizing(server->focused_toplevel->xdg_toplevel, false);
|
wlr_xdg_toplevel_set_resizing(server->focused_toplevel->xdg,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_cursor_move(struct absinthe_server *server)
|
static void
|
||||||
|
process_cursor_move(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
struct absinthe_toplevel *toplevel = server->focused_toplevel;
|
struct absinthe_toplevel *toplevel = server->focused_toplevel;
|
||||||
|
|
||||||
@@ -22,16 +25,14 @@ static void process_cursor_move(struct absinthe_server *server)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (toplevel->fullscreen) {
|
if (toplevel->fullscreen) {
|
||||||
toplevel->prev_geometry = toplevel->geometry;
|
toplevel->prev_geom = toplevel->geom;
|
||||||
absinthe_toplevel_set_fullscreen(toplevel, false);
|
toplevel_set_fullscreen(toplevel, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t new_x, new_y;
|
uint32_t new_x, new_y;
|
||||||
new_x = server->cursor->x - server->grab_x + server->grabbed_geometry.x;
|
new_x = server->cursor->x - server->grab_x + server->grab_geom.x;
|
||||||
new_y = server->cursor->y - server->grab_y + server->grabbed_geometry.y;
|
new_y = server->cursor->y - server->grab_y + server->grab_geom.y;
|
||||||
toplevel->geometry.x = new_x;
|
toplevel_set_pos(toplevel, new_x, new_y);
|
||||||
toplevel->geometry.y = new_y;
|
|
||||||
absinthe_toplevel_set_position(toplevel, new_x, new_y);
|
|
||||||
|
|
||||||
if (toplevel->tiled) {
|
if (toplevel->tiled) {
|
||||||
toplevel->tiled = false;
|
toplevel->tiled = false;
|
||||||
@@ -39,13 +40,14 @@ static void process_cursor_move(struct absinthe_server *server)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new_geometry)
|
static void
|
||||||
|
apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new_geometry)
|
||||||
{
|
{
|
||||||
int32_t min_width = toplevel->xdg_toplevel->current.min_width;
|
int32_t min_width = toplevel->xdg->current.min_width;
|
||||||
int32_t min_height = toplevel->xdg_toplevel->current.min_height;
|
int32_t min_height = toplevel->xdg->current.min_height;
|
||||||
|
|
||||||
int32_t max_width = toplevel->xdg_toplevel->current.max_width;
|
int32_t max_width = toplevel->xdg->current.max_width;
|
||||||
int32_t max_height = toplevel->xdg_toplevel->current.max_height;
|
int32_t max_height = toplevel->xdg->current.max_height;
|
||||||
|
|
||||||
if (max_width == 0)
|
if (max_width == 0)
|
||||||
max_width = 10000;
|
max_width = 10000;
|
||||||
@@ -53,21 +55,24 @@ static void apply_resize(struct absinthe_toplevel *toplevel, struct wlr_box *new
|
|||||||
if (max_height == 0)
|
if (max_height == 0)
|
||||||
max_height = 10000;
|
max_height = 10000;
|
||||||
|
|
||||||
if (!(new_geometry->width >= min_width && new_geometry->width <= max_width)) {
|
if (!(new_geometry->width >= min_width &&
|
||||||
new_geometry->width = toplevel->geometry.width;
|
new_geometry->width <= max_width)) {
|
||||||
new_geometry->x = toplevel->geometry.x;
|
new_geometry->width = toplevel->geom.width;
|
||||||
|
new_geometry->x = toplevel->geom.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(new_geometry->height >= min_height && new_geometry->height <= max_height)) {
|
if (!(new_geometry->height >= min_height &&
|
||||||
new_geometry->height = toplevel->geometry.height;
|
new_geometry->height <= max_height)) {
|
||||||
new_geometry->y = toplevel->geometry.y;
|
new_geometry->height = toplevel->geom.height;
|
||||||
|
new_geometry->y = toplevel->geom.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
absinthe_toplevel_set_size(toplevel, new_geometry->width, new_geometry->height);
|
toplevel_set_size(toplevel, new_geometry->width, new_geometry->height);
|
||||||
absinthe_toplevel_set_position(toplevel, new_geometry->x, new_geometry->y);
|
toplevel_set_pos(toplevel, new_geometry->x, new_geometry->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_cursor_resize(struct absinthe_server *server)
|
static void
|
||||||
|
process_cursor_resize(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
struct absinthe_toplevel *toplevel = server->focused_toplevel;
|
struct absinthe_toplevel *toplevel = server->focused_toplevel;
|
||||||
|
|
||||||
@@ -78,7 +83,7 @@ static void process_cursor_resize(struct absinthe_server *server)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (toplevel->fullscreen)
|
if (toplevel->fullscreen)
|
||||||
absinthe_toplevel_set_fullscreen(toplevel, false);
|
toplevel_set_fullscreen(toplevel, false);
|
||||||
|
|
||||||
if (toplevel->tiled) {
|
if (toplevel->tiled) {
|
||||||
toplevel->tiled = false;
|
toplevel->tiled = false;
|
||||||
@@ -86,10 +91,10 @@ static void process_cursor_resize(struct absinthe_server *server)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t new_x, new_y, new_width, new_height;
|
int32_t new_x, new_y, new_width, new_height;
|
||||||
new_x = server->grabbed_geometry.x;
|
new_x = server->grab_geom.x;
|
||||||
new_y = server->grabbed_geometry.y;
|
new_y = server->grab_geom.y;
|
||||||
new_width = server->grabbed_geometry.width;
|
new_width = server->grab_geom.width;
|
||||||
new_height = server->grabbed_geometry.height;
|
new_height = server->grab_geom.height;
|
||||||
|
|
||||||
int32_t dx = server->cursor->x - server->grab_x;
|
int32_t dx = server->cursor->x - server->grab_x;
|
||||||
int32_t dy = server->cursor->y - server->grab_y;
|
int32_t dy = server->cursor->y - server->grab_y;
|
||||||
@@ -97,24 +102,24 @@ static void process_cursor_resize(struct absinthe_server *server)
|
|||||||
if (dx == 0 && dy == 0)
|
if (dx == 0 && dy == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (server->cursor_resize_corner) {
|
switch (server->resize_corner) {
|
||||||
case ABSINTHE_CURSOR_RESIZE_CORNER_TOP_LEFT:
|
case TOP_LEFT:
|
||||||
new_x += dx;
|
new_x += dx;
|
||||||
new_y += dy;
|
new_y += dy;
|
||||||
new_width -= dx;
|
new_width -= dx;
|
||||||
new_height -= dy;
|
new_height -= dy;
|
||||||
break;
|
break;
|
||||||
case ABSINTHE_CURSOR_RESIZE_CORNER_TOP_RIGHT:
|
case TOP_RIGHT:
|
||||||
new_y += dy;
|
new_y += dy;
|
||||||
new_width += dx;
|
new_width += dx;
|
||||||
new_height -= dy;
|
new_height -= dy;
|
||||||
break;
|
break;
|
||||||
case ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_LEFT:
|
case BOTTOM_LEFT:
|
||||||
new_x += dx;
|
new_x += dx;
|
||||||
new_width -= dx;
|
new_width -= dx;
|
||||||
new_height += dy;
|
new_height += dy;
|
||||||
break;
|
break;
|
||||||
case ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_RIGHT:
|
case BOTTOM_RIGHT:
|
||||||
new_width += dx;
|
new_width += dx;
|
||||||
new_height += dy;
|
new_height += dy;
|
||||||
break;
|
break;
|
||||||
@@ -134,16 +139,19 @@ static void process_cursor_resize(struct absinthe_server *server)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_cursor_motion(struct absinthe_server *server, uint32_t time)
|
void
|
||||||
|
process_cursor_motion(struct absinthe_server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
struct wlr_seat *seat = server->seat;
|
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
|
toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx,
|
||||||
|
&sy);
|
||||||
|
struct wlr_seat *seat = server->seat;
|
||||||
|
|
||||||
if (server->cursor_mode == ABSINTHE_CURSOR_MOVE) {
|
if (server->cursor_mode == CURSOR_MOVE) {
|
||||||
process_cursor_move(server);
|
process_cursor_move(server);
|
||||||
return;
|
return;
|
||||||
} else if (server->cursor_mode == ABSINTHE_CURSOR_RESIZE) {
|
} else if (server->cursor_mode == CURSOR_RESIZE) {
|
||||||
process_cursor_resize(server);
|
process_cursor_resize(server);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-15
@@ -1,11 +1,13 @@
|
|||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "absinthe-toplevel.h"
|
#include "config.h"
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
|
#include "toplevel.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void focus_toplevel(struct absinthe_toplevel *toplevel)
|
void
|
||||||
|
focus_toplevel(struct absinthe_toplevel *toplevel)
|
||||||
{
|
{
|
||||||
if (!toplevel)
|
if (!toplevel)
|
||||||
return;
|
return;
|
||||||
@@ -15,26 +17,31 @@ void focus_toplevel(struct absinthe_toplevel *toplevel)
|
|||||||
struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface;
|
struct wlr_surface *prev_surface = seat->keyboard_state.focused_surface;
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (toplevel->type == ABSINTHE_TOPLEVEL_X11)
|
if (toplevel->type == TOPLEVEL_X11)
|
||||||
surface = toplevel->xwayland_surface->surface;
|
surface = toplevel->xw->surface;
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
surface = toplevel->xdg_toplevel->base->surface;
|
surface = toplevel->xdg->base->surface;
|
||||||
|
|
||||||
if (surface == prev_surface)
|
if (surface == prev_surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (prev_surface) {
|
if (prev_surface) {
|
||||||
struct wlr_xdg_toplevel *prev_toplevel = wlr_xdg_toplevel_try_from_wlr_surface(prev_surface);
|
struct wlr_xdg_toplevel *prev_toplevel =
|
||||||
|
wlr_xdg_toplevel_try_from_wlr_surface(prev_surface);
|
||||||
if (prev_toplevel) {
|
if (prev_toplevel) {
|
||||||
wlr_xdg_toplevel_set_activated(prev_toplevel, false);
|
wlr_xdg_toplevel_set_activated(prev_toplevel, false);
|
||||||
absinthe_toplevel_set_border_color(prev_toplevel->base->data, unfocused_border_color);
|
toplevel_set_border_color(prev_toplevel->base->data,
|
||||||
|
unfocused_bc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
struct wlr_xwayland_surface *prev_xwayland_surface =
|
struct wlr_xwayland_surface *prev_xwayland_surface =
|
||||||
wlr_xwayland_surface_try_from_wlr_surface(prev_surface);
|
wlr_xwayland_surface_try_from_wlr_surface(prev_surface);
|
||||||
if (prev_xwayland_surface)
|
if (prev_xwayland_surface)
|
||||||
absinthe_toplevel_set_border_color(prev_surface->data, unfocused_border_color);
|
toplevel_set_border_color(prev_surface->data,
|
||||||
|
unfocused_bc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
toplevel->server->focused_toplevel = toplevel;
|
toplevel->server->focused_toplevel = toplevel;
|
||||||
@@ -43,16 +50,18 @@ void focus_toplevel(struct absinthe_toplevel *toplevel)
|
|||||||
wlr_scene_node_raise_to_top(&toplevel->scene_tree->node);
|
wlr_scene_node_raise_to_top(&toplevel->scene_tree->node);
|
||||||
wl_list_remove(&toplevel->flink);
|
wl_list_remove(&toplevel->flink);
|
||||||
wl_list_insert(&server->focus_stack, &toplevel->flink);
|
wl_list_insert(&server->focus_stack, &toplevel->flink);
|
||||||
if (toplevel->type != ABSINTHE_TOPLEVEL_X11)
|
if (toplevel->type != TOPLEVEL_X11)
|
||||||
wlr_xdg_toplevel_set_activated(toplevel->xdg_toplevel, true);
|
wlr_xdg_toplevel_set_activated(toplevel->xdg, true);
|
||||||
absinthe_toplevel_set_border_color(toplevel, focused_border_color);
|
toplevel_set_border_color(toplevel, focused_bc);
|
||||||
|
|
||||||
if (keyboard)
|
if (keyboard)
|
||||||
wlr_seat_keyboard_notify_enter(seat, surface, keyboard->keycodes, keyboard->num_keycodes,
|
wlr_seat_keyboard_notify_enter(seat, surface,
|
||||||
|
keyboard->keycodes, keyboard->num_keycodes,
|
||||||
&keyboard->modifiers);
|
&keyboard->modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct absinthe_toplevel *focus_get_topmost(struct absinthe_server *server)
|
struct absinthe_toplevel *
|
||||||
|
focus_get_topmost(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
struct absinthe_toplevel *toplevel;
|
struct absinthe_toplevel *toplevel;
|
||||||
wl_list_for_each(toplevel, &server->focus_stack, flink)
|
wl_list_for_each(toplevel, &server->focus_stack, flink)
|
||||||
@@ -63,7 +72,8 @@ struct absinthe_toplevel *focus_get_topmost(struct absinthe_server *server)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void focus_next(struct absinthe_server *server)
|
void
|
||||||
|
focus_next(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
struct absinthe_toplevel *toplevel = focus_get_topmost(server);
|
struct absinthe_toplevel *toplevel = focus_get_topmost(server);
|
||||||
if (!toplevel)
|
if (!toplevel)
|
||||||
@@ -79,7 +89,8 @@ void focus_next(struct absinthe_server *server)
|
|||||||
focus_toplevel(next);
|
focus_toplevel(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void focus_prev(struct absinthe_server *server)
|
void
|
||||||
|
focus_prev(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
struct absinthe_toplevel *toplevel = focus_get_topmost(server);
|
struct absinthe_toplevel *toplevel = focus_get_topmost(server);
|
||||||
if (!toplevel)
|
if (!toplevel)
|
||||||
|
|||||||
+38
-24
@@ -5,21 +5,25 @@
|
|||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "toplevel.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void keyboard_handle_modifiers(struct wl_listener *listener, void *data)
|
void
|
||||||
|
handle_modifiers(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_keyboard *keyboard = wl_container_of(listener, keyboard, modifiers);
|
struct absinthe_keyboard *keyboard = wl_container_of(listener, keyboard,
|
||||||
|
modifiers);
|
||||||
|
|
||||||
wlr_seat_set_keyboard(keyboard->server->seat, keyboard->wlr_keyboard);
|
wlr_seat_set_keyboard(keyboard->server->seat, keyboard->wlr);
|
||||||
wlr_seat_keyboard_notify_modifiers(keyboard->server->seat, &keyboard->wlr_keyboard->modifiers);
|
wlr_seat_keyboard_notify_modifiers(keyboard->server->seat,
|
||||||
|
&keyboard->wlr->modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t keysym)
|
static bool
|
||||||
|
handle_keybind(struct absinthe_server *server, xkb_keysym_t keysym)
|
||||||
{
|
{
|
||||||
switch (keysym) {
|
switch (keysym) {
|
||||||
case XKB_KEY_Escape:
|
case XKB_KEY_Escape:
|
||||||
@@ -35,7 +39,7 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t
|
|||||||
break;
|
break;
|
||||||
case XKB_KEY_f:
|
case XKB_KEY_f:
|
||||||
if (server->focused_toplevel)
|
if (server->focused_toplevel)
|
||||||
absinthe_toplevel_set_fullscreen(server->focused_toplevel,
|
toplevel_set_fullscreen(server->focused_toplevel,
|
||||||
!server->focused_toplevel->fullscreen);
|
!server->focused_toplevel->fullscreen);
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_j:
|
case XKB_KEY_j:
|
||||||
@@ -45,26 +49,29 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t
|
|||||||
focus_prev(server);
|
focus_prev(server);
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_h:
|
case XKB_KEY_h:
|
||||||
if (server->focused_output && server->focused_output->main_stack_width > 0.15) {
|
if (server->focused_output &&
|
||||||
server->focused_output->main_stack_width -= 0.1;
|
server->focused_output->mstack_width > 0.15) {
|
||||||
|
server->focused_output->mstack_width -= 0.1;
|
||||||
layout_arrange(server->focused_output);
|
layout_arrange(server->focused_output);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_l:
|
case XKB_KEY_l:
|
||||||
if (server->focused_output && server->focused_output->main_stack_width < 0.9) {
|
if (server->focused_output &&
|
||||||
server->focused_output->main_stack_width += 0.1;
|
server->focused_output->mstack_width < 0.9) {
|
||||||
|
server->focused_output->mstack_width += 0.1;
|
||||||
layout_arrange(server->focused_output);
|
layout_arrange(server->focused_output);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_H:
|
case XKB_KEY_H:
|
||||||
if (server->focused_output) {
|
if (server->focused_output) {
|
||||||
server->focused_output->main_stack_size += 1;
|
server->focused_output->mstack_size += 1;
|
||||||
layout_arrange(server->focused_output);
|
layout_arrange(server->focused_output);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XKB_KEY_L:
|
case XKB_KEY_L:
|
||||||
if (server->focused_output && server->focused_output->main_stack_size > 1) {
|
if (server->focused_output &&
|
||||||
server->focused_output->main_stack_size -= 1;
|
server->focused_output->mstack_size > 1) {
|
||||||
|
server->focused_output->mstack_size -= 1;
|
||||||
layout_arrange(server->focused_output);
|
layout_arrange(server->focused_output);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -74,33 +81,40 @@ static bool keyboard_handle_keybind(struct absinthe_server *server, xkb_keysym_t
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_handle_key(struct wl_listener *listener, void *data)
|
void
|
||||||
|
handle_key(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct absinthe_keyboard *keyboard = wl_container_of(listener, keyboard,
|
||||||
|
key);
|
||||||
struct wlr_keyboard_key_event *event = data;
|
struct wlr_keyboard_key_event *event = data;
|
||||||
|
|
||||||
uint32_t keycode = event->keycode + 8;
|
uint32_t keycode = event->keycode + 8;
|
||||||
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr_keyboard);
|
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr);
|
||||||
const xkb_keysym_t *syms;
|
const xkb_keysym_t *syms;
|
||||||
int nsyms = xkb_state_key_get_syms(keyboard->wlr_keyboard->xkb_state, keycode, &syms);
|
int nsyms = xkb_state_key_get_syms(keyboard->wlr->xkb_state, keycode,
|
||||||
|
&syms);
|
||||||
|
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
if ((modifiers & WLR_MODIFIER_ALT) && (event->state == WL_KEYBOARD_KEY_STATE_PRESSED)) {
|
if ((modifiers & WLR_MODIFIER_ALT) &&
|
||||||
|
(event->state == WL_KEYBOARD_KEY_STATE_PRESSED)) {
|
||||||
for (int i = 0; i < nsyms; ++i) {
|
for (int i = 0; i < nsyms; ++i) {
|
||||||
handled = keyboard_handle_keybind(keyboard->server, syms[i]);
|
handled = handle_keybind(keyboard->server, syms[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
wlr_seat_set_keyboard(keyboard->server->seat, keyboard->wlr_keyboard);
|
wlr_seat_set_keyboard(keyboard->server->seat, keyboard->wlr);
|
||||||
wlr_seat_keyboard_notify_key(keyboard->server->seat, event->time_msec, event->keycode, event->state);
|
wlr_seat_keyboard_notify_key(keyboard->server->seat,
|
||||||
|
event->time_msec, event->keycode, event->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_handle_destroy(struct wl_listener *listener, void *data)
|
void
|
||||||
|
handle_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_keyboard *keyboard = wl_container_of(listener, keyboard, modifiers);
|
struct absinthe_keyboard *keyboard = wl_container_of(listener, keyboard,
|
||||||
|
modifiers);
|
||||||
|
|
||||||
wl_list_remove(&keyboard->modifiers.link);
|
wl_list_remove(&keyboard->modifiers.link);
|
||||||
wl_list_remove(&keyboard->key.link);
|
wl_list_remove(&keyboard->key.link);
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
void
|
||||||
|
layer_surface_map(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void
|
||||||
|
layer_surface_unmap(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void
|
||||||
|
layer_surface_commit(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void
|
||||||
|
layer_surface_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
+39
-28
@@ -1,8 +1,10 @@
|
|||||||
#include "absinthe-toplevel.h"
|
#include "config.h"
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
|
#include "toplevel.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void layout_arrange(struct absinthe_output *output)
|
void
|
||||||
|
layout_arrange(struct absinthe_output *output)
|
||||||
{
|
{
|
||||||
if (!output)
|
if (!output)
|
||||||
return;
|
return;
|
||||||
@@ -13,14 +15,15 @@ void layout_arrange(struct absinthe_output *output)
|
|||||||
{
|
{
|
||||||
if (toplevel->output == output && toplevel->tiled) {
|
if (toplevel->output == output && toplevel->tiled) {
|
||||||
toplevels_count++;
|
toplevels_count++;
|
||||||
wlr_scene_node_set_enabled(&toplevel->scene_tree->node, true);
|
wlr_scene_node_set_enabled(&toplevel->scene_tree->node,
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toplevels_count < 1)
|
if (toplevels_count < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32_t output_gap = ABSINTHE_OUTPUT_GAP;
|
int32_t output_gap = OUTPUT_GAP;
|
||||||
|
|
||||||
if (toplevels_count == 1) {
|
if (toplevels_count == 1) {
|
||||||
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
||||||
@@ -28,32 +31,36 @@ void layout_arrange(struct absinthe_output *output)
|
|||||||
if (toplevel->output == output && toplevel->tiled)
|
if (toplevel->output == output && toplevel->tiled)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
toplevel->geometry.x = output->geometry.x + output_gap;
|
int32_t new_x = output->geom.x + output_gap;
|
||||||
toplevel->geometry.y = output->geometry.y + output_gap;
|
int32_t new_y = output->geom.y + output_gap;
|
||||||
absinthe_toplevel_set_size(toplevel, output->geometry.width - 2 * output_gap,
|
toplevel_set_size(toplevel, output->geom.width - 2 * output_gap,
|
||||||
output->geometry.height - 2 * output_gap);
|
output->geom.height - 2 * output_gap);
|
||||||
|
toplevel_set_pos(toplevel, new_x, new_y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t layout_gap = ABSINTHE_LAYOUT_GAP;
|
int32_t layout_gap = LAYOUT_GAP;
|
||||||
int32_t main_stack_width = (toplevels_count <= output->main_stack_size)
|
int32_t main_stack_width = (toplevels_count <= output->mstack_size) ?
|
||||||
? output->geometry.width - 2 * output_gap
|
output->geom.width - 2 * output_gap :
|
||||||
: output->main_stack_width * (output->geometry.width - 2 * output_gap);
|
output->mstack_width * (output->geom.width - 2 * output_gap);
|
||||||
int32_t width = output->geometry.width - main_stack_width - 2 * output_gap - layout_gap;
|
int32_t width = output->geom.width - main_stack_width - 2 * output_gap -
|
||||||
|
layout_gap;
|
||||||
int32_t height;
|
int32_t height;
|
||||||
int32_t dy = output_gap;
|
int32_t dy = output_gap;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if (toplevels_count <= output->main_stack_size) {
|
if (toplevels_count <= output->mstack_size) {
|
||||||
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
||||||
{
|
{
|
||||||
if (toplevel->output != output || !toplevel->tiled)
|
if (toplevel->output != output || !toplevel->tiled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
height = (output->geometry.height - dy - output_gap) / (toplevels_count - i);
|
height = (output->geom.height - dy - output_gap) /
|
||||||
toplevel->geometry.x = output->geometry.x + output_gap;
|
(toplevels_count - i);
|
||||||
toplevel->geometry.y = output->geometry.y + dy;
|
int32_t new_x = output->geom.x + output_gap;
|
||||||
absinthe_toplevel_set_size(toplevel, main_stack_width, height);
|
int32_t new_y = output->geom.y + dy;
|
||||||
|
toplevel_set_pos(toplevel, new_x, new_y);
|
||||||
|
toplevel_set_size(toplevel, main_stack_width, height);
|
||||||
dy += height + layout_gap;
|
dy += height + layout_gap;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
@@ -66,19 +73,23 @@ void layout_arrange(struct absinthe_output *output)
|
|||||||
if (toplevel->output != output || !toplevel->tiled)
|
if (toplevel->output != output || !toplevel->tiled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (i < output->main_stack_size) {
|
if (i < output->mstack_size) {
|
||||||
height = (output->geometry.height - dy - output_gap) / (output->main_stack_size - i);
|
height = (output->geom.height - dy - output_gap) /
|
||||||
toplevel->geometry.x = output->geometry.x + output_gap;
|
(output->mstack_size - i);
|
||||||
toplevel->geometry.y = output->geometry.y + dy;
|
int32_t new_x = output->geom.x + output_gap;
|
||||||
absinthe_toplevel_set_size(toplevel, main_stack_width, height);
|
int32_t new_y = output->geom.y + dy;
|
||||||
|
toplevel_set_pos(toplevel, new_x, new_y);
|
||||||
|
toplevel_set_size(toplevel, main_stack_width, height);
|
||||||
dy += height + layout_gap;
|
dy += height + layout_gap;
|
||||||
} else {
|
} else {
|
||||||
if (i == output->main_stack_size)
|
if (i == output->mstack_size)
|
||||||
dy = output_gap;
|
dy = output_gap;
|
||||||
height = (output->geometry.height - dy - output_gap) / (toplevels_count - i);
|
height = (output->geom.height - dy - output_gap) /
|
||||||
toplevel->geometry.x = output->geometry.x + main_stack_width + layout_gap + output_gap;
|
(toplevels_count - i);
|
||||||
toplevel->geometry.y = output->geometry.y + dy;
|
toplevel->geom.x = output->geom.x + main_stack_width +
|
||||||
absinthe_toplevel_set_size(toplevel, width, height);
|
layout_gap + output_gap;
|
||||||
|
toplevel->geom.y = output->geom.y + dy;
|
||||||
|
toplevel_set_size(toplevel, width, height);
|
||||||
dy += height + layout_gap;
|
dy += height + layout_gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-197
@@ -1,197 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
|
||||||
#include <wlr/types/wlr_data_control_v1.h>
|
|
||||||
#include <wlr/types/wlr_data_device.h>
|
|
||||||
#include <wlr/types/wlr_drm.h>
|
|
||||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
|
||||||
#include <wlr/types/wlr_ext_foreign_toplevel_list_v1.h>
|
|
||||||
#include <wlr/types/wlr_fractional_scale_v1.h>
|
|
||||||
#include <wlr/types/wlr_output_management_v1.h>
|
|
||||||
#include <wlr/types/wlr_presentation_time.h>
|
|
||||||
#include <wlr/types/wlr_screencopy_v1.h>
|
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
|
||||||
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
|
||||||
#include <wlr/types/wlr_viewporter.h>
|
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
|
||||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
|
||||||
#include <wlr/util/log.h>
|
|
||||||
|
|
||||||
#include "output.h"
|
|
||||||
#include "seat.h"
|
|
||||||
#include "server.h"
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
wlr_log_init(WLR_DEBUG, NULL);
|
|
||||||
|
|
||||||
struct absinthe_server server = {0};
|
|
||||||
|
|
||||||
server.display = wl_display_create();
|
|
||||||
if (!server.display) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to create wl_display");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.backend = wlr_backend_autocreate(wl_display_get_event_loop(server.display), NULL);
|
|
||||||
if (!server.backend) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to create wlr_backend");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.renderer = wlr_renderer_autocreate(server.backend);
|
|
||||||
if (!server.renderer) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to create wlr_renderer");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_renderer_init_wl_shm(server.renderer, server.display);
|
|
||||||
|
|
||||||
server.scene = wlr_scene_create();
|
|
||||||
if (wlr_renderer_get_texture_formats(server.renderer, WLR_BUFFER_CAP_DMABUF)) {
|
|
||||||
wlr_drm_create(server.display, server.renderer);
|
|
||||||
wlr_scene_set_linux_dmabuf_v1(
|
|
||||||
server.scene, wlr_linux_dmabuf_v1_create_with_renderer(server.display, 5, server.renderer));
|
|
||||||
}
|
|
||||||
|
|
||||||
server.allocator = wlr_allocator_autocreate(server.backend, server.renderer);
|
|
||||||
if (!server.allocator) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to create wlr_allocator");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
server.compositor = wlr_compositor_create(server.display, 6, server.renderer);
|
|
||||||
wlr_subcompositor_create(server.display);
|
|
||||||
wlr_data_device_manager_create(server.display);
|
|
||||||
wlr_screencopy_manager_v1_create(server.display);
|
|
||||||
wlr_data_control_manager_v1_create(server.display);
|
|
||||||
wlr_viewporter_create(server.display);
|
|
||||||
wlr_single_pixel_buffer_manager_v1_create(server.display);
|
|
||||||
wlr_fractional_scale_manager_v1_create(server.display, 1);
|
|
||||||
wlr_presentation_create(server.display, server.backend, 2);
|
|
||||||
wlr_alpha_modifier_v1_create(server.display);
|
|
||||||
wlr_export_dmabuf_manager_v1_create(server.display);
|
|
||||||
wlr_ext_foreign_toplevel_list_v1_create(server.display, 1);
|
|
||||||
|
|
||||||
wlr_server_decoration_manager_set_default_mode(wlr_server_decoration_manager_create(server.display),
|
|
||||||
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
|
||||||
server.xdg_decoration_mgr = wlr_xdg_decoration_manager_v1_create(server.display);
|
|
||||||
server.new_xdg_decoration.notify = server_new_xdg_decoration;
|
|
||||||
wl_signal_add(&server.xdg_decoration_mgr->events.new_toplevel_decoration, &server.new_xdg_decoration);
|
|
||||||
|
|
||||||
wl_list_init(&server.outputs);
|
|
||||||
server.new_output.notify = server_new_output;
|
|
||||||
wl_signal_add(&server.backend->events.new_output, &server.new_output);
|
|
||||||
|
|
||||||
server.output_layout = wlr_output_layout_create(server.display);
|
|
||||||
server.output_layout_change.notify = outputs_update;
|
|
||||||
wl_signal_add(&server.output_layout->events.change, &server.output_layout_change);
|
|
||||||
|
|
||||||
server.output_mgr = wlr_output_manager_v1_create(server.display);
|
|
||||||
|
|
||||||
wlr_xdg_output_manager_v1_create(server.display, server.output_layout);
|
|
||||||
|
|
||||||
server.scene_layout = wlr_scene_attach_output_layout(server.scene, server.output_layout);
|
|
||||||
|
|
||||||
wl_list_init(&server.toplevels);
|
|
||||||
wl_list_init(&server.focus_stack);
|
|
||||||
|
|
||||||
server.xdg_shell = wlr_xdg_shell_create(server.display, 6);
|
|
||||||
server.new_xdg_toplevel.notify = server_new_xdg_toplevel;
|
|
||||||
wl_signal_add(&server.xdg_shell->events.new_toplevel, &server.new_xdg_toplevel);
|
|
||||||
server.new_xdg_popup.notify = server_new_xdg_popup;
|
|
||||||
wl_signal_add(&server.xdg_shell->events.new_popup, &server.new_xdg_popup);
|
|
||||||
|
|
||||||
server.cursor = wlr_cursor_create();
|
|
||||||
wlr_cursor_attach_output_layout(server.cursor, server.output_layout);
|
|
||||||
|
|
||||||
server.cursor_mgr = wlr_xcursor_manager_create(NULL, 24);
|
|
||||||
|
|
||||||
server.cursor_mode = ABSINTHE_CURSOR_PASSTHROUGH;
|
|
||||||
server.cursor_motion.notify = server_cursor_motion;
|
|
||||||
wl_signal_add(&server.cursor->events.motion, &server.cursor_motion);
|
|
||||||
server.cursor_motion_absolute.notify = server_cursor_motion_absolute;
|
|
||||||
wl_signal_add(&server.cursor->events.motion_absolute, &server.cursor_motion_absolute);
|
|
||||||
server.cursor_button.notify = server_cursor_button;
|
|
||||||
wl_signal_add(&server.cursor->events.button, &server.cursor_button);
|
|
||||||
server.cursor_axis.notify = server_cursor_axis;
|
|
||||||
wl_signal_add(&server.cursor->events.axis, &server.cursor_axis);
|
|
||||||
server.cursor_frame.notify = server_cursor_frame;
|
|
||||||
wl_signal_add(&server.cursor->events.frame, &server.cursor_frame);
|
|
||||||
|
|
||||||
wl_list_init(&server.keyboards);
|
|
||||||
server.new_input.notify = server_new_input;
|
|
||||||
wl_signal_add(&server.backend->events.new_input, &server.new_input);
|
|
||||||
server.seat = wlr_seat_create(server.display, "seat0");
|
|
||||||
server.request_cursor.notify = seat_request_cursor;
|
|
||||||
wl_signal_add(&server.seat->events.request_set_cursor, &server.request_cursor);
|
|
||||||
server.pointer_focus_change.notify = seat_pointer_focus_change;
|
|
||||||
wl_signal_add(&server.seat->pointer_state.events.focus_change, &server.pointer_focus_change);
|
|
||||||
server.request_set_selection.notify = seat_request_set_selection;
|
|
||||||
wl_signal_add(&server.seat->events.request_set_selection, &server.request_set_selection);
|
|
||||||
|
|
||||||
unsetenv("DISPLAY");
|
|
||||||
|
|
||||||
const char *socket = wl_display_add_socket_auto(server.display);
|
|
||||||
if (!socket) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to add socket");
|
|
||||||
wlr_backend_destroy(server.backend);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wlr_backend_start(server.backend)) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to start wlr_backend");
|
|
||||||
wlr_backend_destroy(server.backend);
|
|
||||||
wl_display_destroy(server.display);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if ((server.xwayland = wlr_xwayland_create(server.display, server.compositor, 1))) {
|
|
||||||
server.xwayland_ready.notify = server_xwayland_ready;
|
|
||||||
wl_signal_add(&server.xwayland->events.ready, &server.xwayland_ready);
|
|
||||||
server.xwayland_new_surface.notify = server_xwayland_new_surface;
|
|
||||||
wl_signal_add(&server.xwayland->events.new_surface, &server.xwayland_new_surface);
|
|
||||||
|
|
||||||
setenv("DISPLAY", server.xwayland->display_name, 1);
|
|
||||||
wlr_log(WLR_INFO, "Running XWayland, DISPLAY=%s", server.xwayland->display_name);
|
|
||||||
} else {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to setup XWayland, continuing without it");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
setenv("WAYLAND_DISPLAY", socket, true);
|
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "Running absinthe on WAYLAND_DISPLAY=%s", socket);
|
|
||||||
wl_display_run(server.display);
|
|
||||||
|
|
||||||
wl_display_destroy_clients(server.display);
|
|
||||||
|
|
||||||
wl_list_remove(&server.new_xdg_toplevel.link);
|
|
||||||
wl_list_remove(&server.new_xdg_popup.link);
|
|
||||||
wl_list_remove(&server.new_xdg_decoration.link);
|
|
||||||
|
|
||||||
wl_list_remove(&server.cursor_motion.link);
|
|
||||||
wl_list_remove(&server.cursor_motion_absolute.link);
|
|
||||||
wl_list_remove(&server.cursor_button.link);
|
|
||||||
wl_list_remove(&server.cursor_axis.link);
|
|
||||||
wl_list_remove(&server.cursor_frame.link);
|
|
||||||
|
|
||||||
wl_list_remove(&server.new_input.link);
|
|
||||||
wl_list_remove(&server.request_cursor.link);
|
|
||||||
wl_list_remove(&server.pointer_focus_change.link);
|
|
||||||
wl_list_remove(&server.request_set_selection.link);
|
|
||||||
|
|
||||||
wl_list_remove(&server.new_output.link);
|
|
||||||
|
|
||||||
wlr_scene_node_destroy(&server.scene->tree.node);
|
|
||||||
wlr_xcursor_manager_destroy(server.cursor_mgr);
|
|
||||||
wlr_cursor_destroy(server.cursor);
|
|
||||||
wlr_allocator_destroy(server.allocator);
|
|
||||||
wlr_renderer_destroy(server.renderer);
|
|
||||||
wlr_backend_destroy(server.backend);
|
|
||||||
wl_display_destroy(server.display);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+89
-19
@@ -1,15 +1,21 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "focus.h"
|
||||||
|
#include "layout.h"
|
||||||
|
#include "toplevel.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void output_frame(struct wl_listener *listener, void *data)
|
void
|
||||||
|
output_frame(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_output *output = wl_container_of(listener, output, frame);
|
struct timespec now;
|
||||||
|
struct absinthe_output *output = wl_container_of(listener, output,
|
||||||
|
frame);
|
||||||
struct wlr_scene *scene = output->server->scene;
|
struct wlr_scene *scene = output->server->scene;
|
||||||
|
struct wlr_scene_output *scene_output =
|
||||||
struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, output->wlr_output);
|
wlr_scene_get_scene_output(scene, output->wlr);
|
||||||
|
|
||||||
struct absinthe_toplevel *toplevel;
|
struct absinthe_toplevel *toplevel;
|
||||||
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
wl_list_for_each(toplevel, &output->server->toplevels, link)
|
||||||
@@ -21,22 +27,25 @@ void output_frame(struct wl_listener *listener, void *data)
|
|||||||
wlr_scene_output_commit(scene_output, NULL);
|
wlr_scene_output_commit(scene_output, NULL);
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
struct timespec now;
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
wlr_scene_output_send_frame_done(scene_output, &now);
|
wlr_scene_output_send_frame_done(scene_output, &now);
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_request_state(struct wl_listener *listener, void *data)
|
void
|
||||||
|
output_request_state(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_output *output = wl_container_of(listener, output, request_state);
|
struct absinthe_output *output = wl_container_of(listener, output,
|
||||||
|
request_state);
|
||||||
const struct wlr_output_event_request_state *event = data;
|
const struct wlr_output_event_request_state *event = data;
|
||||||
wlr_output_commit_state(output->wlr_output, event->state);
|
wlr_output_commit_state(output->wlr, event->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_destroy(struct wl_listener *listener, void *data)
|
void
|
||||||
|
output_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_output *output = wl_container_of(listener, output, request_state);
|
struct absinthe_output *output = wl_container_of(listener, output,
|
||||||
|
request_state);
|
||||||
|
|
||||||
wl_list_remove(&output->frame.link);
|
wl_list_remove(&output->frame.link);
|
||||||
wl_list_remove(&output->request_state.link);
|
wl_list_remove(&output->request_state.link);
|
||||||
@@ -45,28 +54,89 @@ void output_destroy(struct wl_listener *listener, void *data)
|
|||||||
free(output);
|
free(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void outputs_update(struct wl_listener *listener, void *data)
|
void
|
||||||
|
output_layout_change(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, output_layout_change);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
layout_change);
|
||||||
|
struct wlr_output_configuration_v1 *config =
|
||||||
|
wlr_output_configuration_v1_create();
|
||||||
|
|
||||||
|
struct absinthe_toplevel *toplevel = NULL;
|
||||||
struct absinthe_output *output;
|
struct absinthe_output *output;
|
||||||
|
struct wlr_output_configuration_head_v1 *config_head;
|
||||||
|
|
||||||
wl_list_for_each(output, &server->outputs, link)
|
wl_list_for_each(output, &server->outputs, link)
|
||||||
{
|
{
|
||||||
wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->geometry);
|
if (output->wlr->enabled)
|
||||||
}
|
continue;
|
||||||
|
config_head = wlr_output_configuration_head_v1_create(config,
|
||||||
|
output->wlr);
|
||||||
|
config_head->state.enabled = 0;
|
||||||
|
wlr_output_layout_remove(server->output_layout, output->wlr);
|
||||||
|
|
||||||
|
// closemon(m);
|
||||||
|
// m->m = m->w = (struct wlr_box){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_focused_output(struct absinthe_server *server)
|
wl_list_for_each(output, &server->outputs, link)
|
||||||
|
{
|
||||||
|
if (output->wlr->enabled &&
|
||||||
|
!wlr_output_layout_get(server->output_layout, output->wlr))
|
||||||
|
wlr_output_layout_add_auto(server->output_layout,
|
||||||
|
toplevel->output->wlr);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_for_each(output, &server->outputs, link)
|
||||||
|
{
|
||||||
|
if (!output->wlr->enabled)
|
||||||
|
continue;
|
||||||
|
config_head = wlr_output_configuration_head_v1_create(config,
|
||||||
|
output->wlr);
|
||||||
|
|
||||||
|
wlr_output_layout_get_box(server->output_layout, output->wlr,
|
||||||
|
&output->geom);
|
||||||
|
|
||||||
|
if ((toplevel = focus_get_topmost(server)) &&
|
||||||
|
toplevel->fullscreen)
|
||||||
|
toplevel_set_size(toplevel, output->geom.width,
|
||||||
|
output->geom.height);
|
||||||
|
|
||||||
|
config_head->state.x = output->geom.x;
|
||||||
|
config_head->state.y = output->geom.y;
|
||||||
|
|
||||||
|
if (!server->focused_output)
|
||||||
|
server->focused_output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server->focused_output && server->focused_output->wlr->enabled) {
|
||||||
|
wl_list_for_each(toplevel, &server->toplevels, link)
|
||||||
|
{
|
||||||
|
if (!toplevel->output) {
|
||||||
|
toplevel->output = server->focused_output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout_arrange(server->focused_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
focus_toplevel(focus_get_topmost(server));
|
||||||
|
wlr_cursor_move(server->cursor, NULL, 0, 0);
|
||||||
|
wlr_output_manager_v1_set_configuration(server->output_mgr, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
update_focused_output(struct absinthe_server *server)
|
||||||
{
|
{
|
||||||
struct absinthe_output *output;
|
struct absinthe_output *output;
|
||||||
int32_t cursor_x = server->cursor->x;
|
int32_t cursor_x = server->cursor->x;
|
||||||
int32_t cursor_y = server->cursor->y;
|
int32_t cursor_y = server->cursor->y;
|
||||||
wl_list_for_each(output, &server->outputs, link)
|
wl_list_for_each(output, &server->outputs, link)
|
||||||
{
|
{
|
||||||
bool cursor_in_output_x =
|
bool cursor_in_output_x = cursor_x >= output->geom.x &&
|
||||||
cursor_x >= output->geometry.x && cursor_x <= output->geometry.x + output->geometry.width;
|
cursor_x <= output->geom.x + output->geom.width;
|
||||||
bool cursor_in_output_y =
|
bool cursor_in_output_y = cursor_y >= output->geom.y &&
|
||||||
cursor_y >= output->geometry.y && cursor_y <= output->geometry.y + output->geometry.height;
|
cursor_y <= output->geom.y + output->geom.height;
|
||||||
if (cursor_in_output_x && cursor_in_output_y) {
|
if (cursor_in_output_x && cursor_in_output_y) {
|
||||||
server->focused_output = output;
|
server->focused_output = output;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+18
-9
@@ -3,28 +3,37 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void seat_request_cursor(struct wl_listener *listener, void *data)
|
void
|
||||||
|
request_cursor(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, request_cursor);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
request_cursor);
|
||||||
struct wlr_seat_pointer_request_set_cursor_event *event = data;
|
struct wlr_seat_pointer_request_set_cursor_event *event = data;
|
||||||
struct wlr_seat_client *client = server->seat->pointer_state.focused_client;
|
struct wlr_seat_client *client =
|
||||||
|
server->seat->pointer_state.focused_client;
|
||||||
|
|
||||||
if (client == event->seat_client)
|
if (client == event->seat_client)
|
||||||
wlr_cursor_set_surface(server->cursor, event->surface, event->hotspot_x, event->hotspot_y);
|
wlr_cursor_set_surface(server->cursor, event->surface,
|
||||||
|
event->hotspot_x, event->hotspot_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void seat_pointer_focus_change(struct wl_listener *listener, void *data)
|
void
|
||||||
|
pointer_focus_change(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, pointer_focus_change);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
pointer_focus_change);
|
||||||
struct wlr_seat_pointer_focus_change_event *event = data;
|
struct wlr_seat_pointer_focus_change_event *event = data;
|
||||||
|
|
||||||
if (!event->new_surface)
|
if (!event->new_surface)
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "default");
|
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr,
|
||||||
|
"default");
|
||||||
}
|
}
|
||||||
|
|
||||||
void seat_request_set_selection(struct wl_listener *listener, void *data)
|
void
|
||||||
|
request_set_selection(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, request_set_selection);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
request_set_selection);
|
||||||
struct wlr_seat_request_set_selection_event *event = data;
|
struct wlr_seat_request_set_selection_event *event = data;
|
||||||
|
|
||||||
wlr_seat_set_selection(server->seat, event->source, event->serial);
|
wlr_seat_set_selection(server->seat, event->source, event->serial);
|
||||||
|
|||||||
+210
-137
@@ -1,15 +1,17 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "absinthe-toplevel-handlers.h"
|
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "focus.h"
|
#include "focus.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
|
#include "layer-surface.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
#include "toplevel-handlers.h"
|
||||||
|
#include "toplevel.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "xdg-decoration.h"
|
#include "xdg-decoration.h"
|
||||||
#include "xdg-popup.h"
|
#include "xdg-popup.h"
|
||||||
@@ -21,9 +23,11 @@
|
|||||||
#include "xwayland.h"
|
#include "xwayland.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void server_new_output(struct wl_listener *listener, void *data)
|
void
|
||||||
|
new_output(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, new_output);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
new_output);
|
||||||
struct wlr_output *wlr_output = data;
|
struct wlr_output *wlr_output = data;
|
||||||
|
|
||||||
wlr_output_init_render(wlr_output, server->allocator, server->renderer);
|
wlr_output_init_render(wlr_output, server->allocator, server->renderer);
|
||||||
@@ -40,166 +44,215 @@ void server_new_output(struct wl_listener *listener, void *data)
|
|||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
|
||||||
struct absinthe_output *output = calloc(1, sizeof(*output));
|
struct absinthe_output *output = calloc(1, sizeof(*output));
|
||||||
output->wlr_output = wlr_output;
|
output->wlr = wlr_output;
|
||||||
output->server = server;
|
output->server = server;
|
||||||
|
|
||||||
output->frame.notify = output_frame;
|
LISTEN(output->frame, output_frame, wlr_output->events.frame);
|
||||||
wl_signal_add(&wlr_output->events.frame, &output->frame);
|
LISTEN(output->request_state, output_request_state,
|
||||||
|
wlr_output->events.request_state);
|
||||||
output->request_state.notify = output_request_state;
|
LISTEN(output->destroy, output_destroy, wlr_output->events.destroy);
|
||||||
wl_signal_add(&wlr_output->events.request_state, &output->request_state);
|
|
||||||
|
|
||||||
output->destroy.notify = output_destroy;
|
|
||||||
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
|
|
||||||
|
|
||||||
wl_list_insert(&server->outputs, &output->link);
|
wl_list_insert(&server->outputs, &output->link);
|
||||||
|
|
||||||
struct wlr_output_layout_output *l_layout =
|
struct wlr_output_layout_output *l_layout =
|
||||||
wlr_output_layout_add_auto(server->output_layout, output->wlr_output);
|
wlr_output_layout_add_auto(server->output_layout, output->wlr);
|
||||||
struct wlr_scene_output *scene_output = wlr_scene_output_create(server->scene, wlr_output);
|
struct wlr_scene_output *scene_output =
|
||||||
wlr_scene_output_layout_add_output(server->scene_layout, l_layout, scene_output);
|
wlr_scene_output_create(server->scene, wlr_output);
|
||||||
wlr_output_layout_get_box(server->output_layout, output->wlr_output, &output->geometry);
|
wlr_scene_output_layout_add_output(server->scene_layout, l_layout,
|
||||||
|
scene_output);
|
||||||
|
wlr_output_layout_get_box(server->output_layout, output->wlr,
|
||||||
|
&output->geom);
|
||||||
|
|
||||||
output->main_stack_size = ABSINTHE_MAIN_STACK_SIZE;
|
output->mstack_size = MSTACK_SIZE;
|
||||||
output->main_stack_width = ABSINTHE_MAIN_STACK_WIDTH;
|
output->mstack_width = MSTACK_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_new_xdg_toplevel(struct wl_listener *listener, void *data)
|
void
|
||||||
|
new_xdg_toplevel(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, new_xdg_toplevel);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
new_xdg_toplevel);
|
||||||
struct wlr_xdg_toplevel *xdg_toplevel = data;
|
struct wlr_xdg_toplevel *xdg_toplevel = data;
|
||||||
|
|
||||||
struct absinthe_toplevel *toplevel = calloc(1, sizeof(*toplevel));
|
struct absinthe_toplevel *toplevel = calloc(1, sizeof(*toplevel));
|
||||||
toplevel->type = ABSINTHE_TOPLEVEL_XDG;
|
toplevel->type = TOPLEVEL_XDG;
|
||||||
toplevel->server = server;
|
toplevel->server = server;
|
||||||
toplevel->xdg_toplevel = xdg_toplevel;
|
toplevel->xdg = xdg_toplevel;
|
||||||
toplevel->xdg_toplevel->base->data = toplevel;
|
toplevel->xdg->base->data = toplevel;
|
||||||
|
|
||||||
toplevel->commit.notify = xdg_toplevel_commit;
|
toplevel->commit.notify = toplevel_commit;
|
||||||
wl_signal_add(&xdg_toplevel->base->surface->events.commit, &toplevel->commit);
|
wl_signal_add(&xdg_toplevel->base->surface->events.commit,
|
||||||
|
&toplevel->commit);
|
||||||
|
|
||||||
toplevel->map.notify = absinthe_toplevel_map;
|
toplevel->map.notify = toplevel_map;
|
||||||
wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel->map);
|
wl_signal_add(&xdg_toplevel->base->surface->events.map, &toplevel->map);
|
||||||
toplevel->unmap.notify = absinthe_toplevel_unmap;
|
toplevel->unmap.notify = toplevel_unmap;
|
||||||
wl_signal_add(&xdg_toplevel->base->surface->events.unmap, &toplevel->unmap);
|
wl_signal_add(&xdg_toplevel->base->surface->events.unmap,
|
||||||
|
&toplevel->unmap);
|
||||||
|
|
||||||
toplevel->destroy.notify = absinthe_toplevel_destroy;
|
toplevel->destroy.notify = toplevel_destroy;
|
||||||
wl_signal_add(&xdg_toplevel->events.destroy, &toplevel->destroy);
|
wl_signal_add(&xdg_toplevel->events.destroy, &toplevel->destroy);
|
||||||
|
|
||||||
toplevel->request_move.notify = absinthe_toplevel_request_move;
|
toplevel->request_move.notify = toplevel_request_move;
|
||||||
wl_signal_add(&xdg_toplevel->events.request_move, &toplevel->request_move);
|
wl_signal_add(&xdg_toplevel->events.request_move,
|
||||||
toplevel->request_resize.notify = absinthe_toplevel_request_resize;
|
&toplevel->request_move);
|
||||||
wl_signal_add(&xdg_toplevel->events.request_resize, &toplevel->request_resize);
|
toplevel->request_resize.notify = toplevel_request_resize;
|
||||||
toplevel->request_maximize.notify = absinthe_toplevel_request_maximize;
|
wl_signal_add(&xdg_toplevel->events.request_resize,
|
||||||
wl_signal_add(&xdg_toplevel->events.request_maximize, &toplevel->request_maximize);
|
&toplevel->request_resize);
|
||||||
toplevel->request_fullscreen.notify = absinthe_toplevel_request_fullscreen;
|
toplevel->request_maximize.notify = toplevel_request_maximize;
|
||||||
wl_signal_add(&xdg_toplevel->events.request_fullscreen, &toplevel->request_fullscreen);
|
wl_signal_add(&xdg_toplevel->events.request_maximize,
|
||||||
|
&toplevel->request_maximize);
|
||||||
|
toplevel->request_fullscreen.notify = toplevel_request_fullscreen;
|
||||||
|
wl_signal_add(&xdg_toplevel->events.request_fullscreen,
|
||||||
|
&toplevel->request_fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_new_xdg_popup(struct wl_listener *listener, void *data)
|
void
|
||||||
|
new_xdg_popup(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, new_xdg_popup);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
new_xdg_popup);
|
||||||
struct wlr_xdg_popup *xdg_popup = data;
|
struct wlr_xdg_popup *xdg_popup = data;
|
||||||
|
|
||||||
struct absinthe_popup *popup = calloc(1, sizeof(*popup));
|
struct absinthe_popup *popup = calloc(1, sizeof(*popup));
|
||||||
popup->xdg_popup = xdg_popup;
|
popup->wlr = xdg_popup;
|
||||||
|
|
||||||
struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(xdg_popup->parent);
|
struct wlr_xdg_surface *parent = wlr_xdg_surface_try_from_wlr_surface(
|
||||||
|
xdg_popup->parent);
|
||||||
struct absinthe_toplevel *parent_toplevel = parent->data;
|
struct absinthe_toplevel *parent_toplevel = parent->data;
|
||||||
struct wlr_scene_tree *parent_tree = parent_toplevel->scene_tree;
|
struct wlr_scene_tree *parent_tree = parent_toplevel->scene_tree;
|
||||||
xdg_popup->base->data = wlr_scene_xdg_surface_create(parent_tree, xdg_popup->base);
|
xdg_popup->base->data = wlr_scene_xdg_surface_create(parent_tree,
|
||||||
|
xdg_popup->base);
|
||||||
|
|
||||||
popup->commit.notify = xdg_popup_commit;
|
popup->commit.notify = xdg_popup_commit;
|
||||||
wl_signal_add(&xdg_popup->base->surface->events.commit, &popup->commit);
|
wl_signal_add(&xdg_popup->base->surface->events.commit, &popup->commit);
|
||||||
|
|
||||||
popup->destroy.notify = xdg_popup_destroy;
|
popup->destroy.notify = xdg_popup_destroy;
|
||||||
wl_signal_add(&xdg_popup->base->surface->events.destroy, &popup->destroy);
|
wl_signal_add(&xdg_popup->base->surface->events.destroy,
|
||||||
|
&popup->destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_new_xdg_decoration(struct wl_listener *listener, void *data)
|
void
|
||||||
|
new_xdg_decoration(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(listener);
|
UNUSED(listener);
|
||||||
struct wlr_xdg_toplevel_decoration_v1 *xdg_decoration = data;
|
struct wlr_xdg_toplevel_decoration_v1 *deco = data;
|
||||||
struct absinthe_toplevel *toplevel = xdg_decoration->toplevel->base->data;
|
struct absinthe_toplevel *toplevel = deco->toplevel->base->data;
|
||||||
toplevel->decoration = xdg_decoration;
|
toplevel->deco = deco;
|
||||||
|
|
||||||
toplevel->decoration_request_mode.notify = xdg_decoration_request_mode;
|
LISTEN(toplevel->deco_request_mode, deco_request_mode,
|
||||||
wl_signal_add(&xdg_decoration->events.request_mode, &toplevel->decoration_request_mode);
|
deco->events.request_mode);
|
||||||
toplevel->decoration_destroy.notify = xdg_decoration_destroy;
|
LISTEN(toplevel->deco_destroy, deco_destroy, deco->events.destroy);
|
||||||
wl_signal_add(&xdg_decoration->events.destroy, &toplevel->decoration_destroy);
|
|
||||||
|
|
||||||
/* Forse server side decoration mode */
|
/* Forse server side decoration mode */
|
||||||
xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration);
|
deco_request_mode(&toplevel->deco_request_mode, toplevel->deco);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
new_layer_surface(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
new_layer_surface);
|
||||||
|
struct wlr_layer_surface_v1 *layer_surface = data;
|
||||||
|
|
||||||
|
if (!layer_surface->output &&
|
||||||
|
!(layer_surface->output = server->focused_output->wlr)) {
|
||||||
|
wlr_layer_surface_v1_destroy(layer_surface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct absinthe_layer_surface *layer = calloc(1, sizeof(*layer));
|
||||||
|
LISTEN(layer->commit, layer_surface_commit,
|
||||||
|
layer_surface->surface->events.commit);
|
||||||
|
LISTEN(layer->unmap, layer_surface_unmap,
|
||||||
|
layer_surface->surface->events.unmap);
|
||||||
|
LISTEN(layer->destroy, layer_surface_destroy,
|
||||||
|
layer_surface->surface->events.destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
void server_xwayland_ready(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_ready(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, xwayland_ready);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
xw_ready);
|
||||||
|
|
||||||
wlr_xwayland_set_seat(server->xwayland, server->seat);
|
wlr_xwayland_set_seat(server->xwayland, server->seat);
|
||||||
|
|
||||||
struct wlr_xcursor *xcursor;
|
struct wlr_xcursor *xcursor;
|
||||||
if ((xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr, "default", 1))) {
|
if ((xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr,
|
||||||
struct wlr_buffer *buffer = wlr_xcursor_image_get_buffer(xcursor->images[0]);
|
"default", 1))) {
|
||||||
wlr_xwayland_set_cursor(server->xwayland, buffer, xcursor->images[0]->hotspot_x,
|
struct wlr_buffer *buffer = wlr_xcursor_image_get_buffer(
|
||||||
|
xcursor->images[0]);
|
||||||
|
wlr_xwayland_set_cursor(server->xwayland, buffer,
|
||||||
|
xcursor->images[0]->hotspot_x,
|
||||||
xcursor->images[0]->hotspot_y);
|
xcursor->images[0]->hotspot_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_xwayland_new_surface(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_new_surface(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, xwayland_new_surface);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
xw_new_surface);
|
||||||
struct wlr_xwayland_surface *surface = data;
|
struct wlr_xwayland_surface *surface = data;
|
||||||
struct absinthe_toplevel *toplevel = calloc(1, sizeof(*toplevel));
|
struct absinthe_toplevel *toplevel = calloc(1, sizeof(*toplevel));
|
||||||
|
|
||||||
toplevel->type = ABSINTHE_TOPLEVEL_X11;
|
toplevel->type = TOPLEVEL_X11;
|
||||||
toplevel->server = server;
|
toplevel->server = server;
|
||||||
toplevel->xwayland_surface = surface;
|
toplevel->xw = surface;
|
||||||
toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel) ? 0 : ABSINTHE_TOPLEVEL_BORDER_WIDTH;
|
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
|
||||||
|
surface->data = toplevel;
|
||||||
|
|
||||||
toplevel->destroy.notify = absinthe_toplevel_destroy;
|
LISTEN(toplevel->destroy, toplevel_destroy, surface->events.destroy);
|
||||||
wl_signal_add(&surface->events.destroy, &toplevel->destroy);
|
LISTEN(toplevel->request_maximize, toplevel_request_maximize,
|
||||||
toplevel->request_maximize.notify = absinthe_toplevel_request_maximize;
|
surface->events.request_maximize);
|
||||||
wl_signal_add(&surface->events.request_maximize, &toplevel->request_maximize);
|
LISTEN(toplevel->request_fullscreen, toplevel_request_fullscreen,
|
||||||
toplevel->request_fullscreen.notify = absinthe_toplevel_request_fullscreen;
|
surface->events.request_fullscreen);
|
||||||
wl_signal_add(&surface->events.request_fullscreen, &toplevel->request_fullscreen);
|
|
||||||
|
|
||||||
toplevel->xwayland_activate.notify = xwayland_activate;
|
LISTEN(toplevel->xw_activate, xwayland_activate,
|
||||||
wl_signal_add(&surface->events.request_activate, &toplevel->xwayland_activate);
|
surface->events.request_activate);
|
||||||
toplevel->xwayland_associate.notify = xwayland_associate;
|
LISTEN(toplevel->xw_associate, xwayland_associate,
|
||||||
wl_signal_add(&surface->events.associate, &toplevel->xwayland_associate);
|
surface->events.associate);
|
||||||
toplevel->xwayland_dissociate.notify = xwayland_dissociate;
|
LISTEN(toplevel->xw_dissociate, xwayland_dissociate,
|
||||||
wl_signal_add(&surface->events.dissociate, &toplevel->xwayland_dissociate);
|
surface->events.dissociate);
|
||||||
toplevel->xwayland_configure.notify = xwayland_configure;
|
LISTEN(toplevel->xw_configure, xwayland_configure,
|
||||||
wl_signal_add(&surface->events.request_configure, &toplevel->xwayland_configure);
|
surface->events.request_configure);
|
||||||
toplevel->xwayland_set_hints.notify = xwayland_set_hints;
|
LISTEN(toplevel->xw_set_hints, xwayland_set_hints,
|
||||||
wl_signal_add(&surface->events.set_hints, &toplevel->xwayland_set_hints);
|
surface->events.set_hints);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void server_cursor_motion(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_motion(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, cursor_motion);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
cursor_motion);
|
||||||
struct wlr_pointer_motion_event *event = data;
|
struct wlr_pointer_motion_event *event = data;
|
||||||
update_focused_output(server);
|
update_focused_output(server);
|
||||||
wlr_cursor_move(server->cursor, &event->pointer->base, event->delta_x, event->delta_y);
|
wlr_cursor_move(server->cursor, &event->pointer->base, event->delta_x,
|
||||||
|
event->delta_y);
|
||||||
process_cursor_motion(server, event->time_msec);
|
process_cursor_motion(server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_cursor_motion_absolute(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_motion_abs(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, cursor_motion_absolute);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
cursor_motion_abs);
|
||||||
struct wlr_pointer_motion_absolute_event *event = data;
|
struct wlr_pointer_motion_absolute_event *event = data;
|
||||||
update_focused_output(server);
|
update_focused_output(server);
|
||||||
wlr_cursor_warp_absolute(server->cursor, &event->pointer->base, event->x, event->y);
|
wlr_cursor_warp_absolute(server->cursor, &event->pointer->base,
|
||||||
|
event->x, event->y);
|
||||||
process_cursor_motion(server, event->time_msec);
|
process_cursor_motion(server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_cursor_button(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_button(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, cursor_button);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
cursor_button);
|
||||||
struct wlr_pointer_button_event *event = data;
|
struct wlr_pointer_button_event *event = data;
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
@@ -208,21 +261,23 @@ void server_cursor_button(struct wl_listener *listener, void *data)
|
|||||||
} else {
|
} else {
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
struct absinthe_toplevel *toplevel =
|
struct absinthe_toplevel *toplevel = toplevel_at(server,
|
||||||
absinthe_toplevel_at(server, server->cursor->x, server->cursor->y, &surface, &sx, &sy);
|
server->cursor->x, server->cursor->y, &surface, &sx, &sy);
|
||||||
|
|
||||||
if (!toplevel)
|
if (!toplevel)
|
||||||
goto handle;
|
goto handle;
|
||||||
|
|
||||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(server->seat);
|
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(
|
||||||
|
server->seat);
|
||||||
uint32_t mods = wlr_keyboard_get_modifiers(keyboard);
|
uint32_t mods = wlr_keyboard_get_modifiers(keyboard);
|
||||||
if (mods & ABSINTHE_CURSOR_MOD) {
|
if (mods & CURSOR_MOD) {
|
||||||
if (event->button == ABSINTHE_CURSOR_MOVE_BUTTON) {
|
if (event->button == CURSOR_MOVE_BUTTON) {
|
||||||
server->cursor_mode = ABSINTHE_CURSOR_MOVE;
|
server->cursor_mode = CURSOR_MOVE;
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "all-scroll");
|
wlr_cursor_set_xcursor(server->cursor,
|
||||||
|
server->cursor_mgr, "all-scroll");
|
||||||
handled = true;
|
handled = true;
|
||||||
} else if (event->button == ABSINTHE_CURSOR_RESIZE_BUTTON) {
|
} else if (event->button == CURSOR_RESIZE_BUTTON) {
|
||||||
server->cursor_mode = ABSINTHE_CURSOR_RESIZE;
|
server->cursor_mode = CURSOR_RESIZE;
|
||||||
handled = true;
|
handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,97 +288,115 @@ void server_cursor_button(struct wl_listener *listener, void *data)
|
|||||||
|
|
||||||
int32_t lx, ly;
|
int32_t lx, ly;
|
||||||
wlr_scene_node_coords(&toplevel->scene_tree->node, &lx, &ly);
|
wlr_scene_node_coords(&toplevel->scene_tree->node, &lx, &ly);
|
||||||
server->grabbed_geometry.x = lx;
|
server->grab_geom.x = lx;
|
||||||
server->grabbed_geometry.y = ly;
|
server->grab_geom.y = ly;
|
||||||
server->grabbed_geometry.width = toplevel->geometry.width;
|
server->grab_geom.width = toplevel->geom.width;
|
||||||
server->grabbed_geometry.height = toplevel->geometry.height;
|
server->grab_geom.height = toplevel->geom.height;
|
||||||
|
|
||||||
if (server->cursor_mode != ABSINTHE_CURSOR_RESIZE)
|
if (server->cursor_mode != CURSOR_RESIZE)
|
||||||
goto handle;
|
goto handle;
|
||||||
|
|
||||||
int32_t width = toplevel->xdg_toplevel->base->geometry.width;
|
int32_t width = toplevel->xdg->base->geometry.width;
|
||||||
int32_t height = toplevel->xdg_toplevel->base->geometry.height;
|
int32_t height = toplevel->xdg->base->geometry.height;
|
||||||
|
|
||||||
if (server->grab_x > (lx + width / 2) && server->grab_y > (ly + height / 2)) {
|
if (server->grab_x > (lx + width / 2) &&
|
||||||
server->cursor_resize_corner = ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_RIGHT;
|
server->grab_y > (ly + height / 2)) {
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "se-resize");
|
server->resize_corner = BOTTOM_RIGHT;
|
||||||
} else if (server->grab_x < (lx + width / 2) && server->grab_y > (ly + height / 2)) {
|
wlr_cursor_set_xcursor(server->cursor,
|
||||||
server->cursor_resize_corner = ABSINTHE_CURSOR_RESIZE_CORNER_BOTTOM_LEFT;
|
server->cursor_mgr, "se-resize");
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "sw-resize");
|
} else if (server->grab_x < (lx + width / 2) &&
|
||||||
} else if (server->grab_x > (lx + width / 2) && server->grab_y < (ly + height / 2)) {
|
server->grab_y > (ly + height / 2)) {
|
||||||
server->cursor_resize_corner = ABSINTHE_CURSOR_RESIZE_CORNER_TOP_RIGHT;
|
server->resize_corner = BOTTOM_LEFT;
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "ne-resize");
|
wlr_cursor_set_xcursor(server->cursor,
|
||||||
|
server->cursor_mgr, "sw-resize");
|
||||||
|
} else if (server->grab_x > (lx + width / 2) &&
|
||||||
|
server->grab_y < (ly + height / 2)) {
|
||||||
|
server->resize_corner = TOP_RIGHT;
|
||||||
|
wlr_cursor_set_xcursor(server->cursor,
|
||||||
|
server->cursor_mgr, "ne-resize");
|
||||||
} else {
|
} else {
|
||||||
server->cursor_resize_corner = ABSINTHE_CURSOR_RESIZE_CORNER_TOP_LEFT;
|
server->resize_corner = TOP_LEFT;
|
||||||
wlr_cursor_set_xcursor(server->cursor, server->cursor_mgr, "nw-resize");
|
wlr_cursor_set_xcursor(server->cursor,
|
||||||
|
server->cursor_mgr, "nw-resize");
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_resizing(toplevel->xdg_toplevel, true);
|
wlr_xdg_toplevel_set_resizing(toplevel->xdg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle:
|
handle:
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
wlr_seat_pointer_notify_button(server->seat, event->time_msec, event->button, event->state);
|
wlr_seat_pointer_notify_button(server->seat, event->time_msec,
|
||||||
|
event->button, event->state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_cursor_axis(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_axis(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, cursor_axis);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
cursor_axis);
|
||||||
struct wlr_pointer_axis_event *event = data;
|
struct wlr_pointer_axis_event *event = data;
|
||||||
wlr_seat_pointer_notify_axis(server->seat, event->time_msec, event->orientation, event->delta,
|
wlr_seat_pointer_notify_axis(server->seat, event->time_msec,
|
||||||
event->delta_discrete, event->source, event->relative_direction);
|
event->orientation, event->delta, event->delta_discrete,
|
||||||
|
event->source, event->relative_direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_cursor_frame(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_frame(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, cursor_frame);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
cursor_frame);
|
||||||
wlr_seat_pointer_notify_frame(server->seat);
|
wlr_seat_pointer_notify_frame(server->seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_new_keyboard(struct absinthe_server *server, struct wlr_input_device *device)
|
static void
|
||||||
|
new_keyboard(struct absinthe_server *server, struct wlr_input_device *device)
|
||||||
{
|
{
|
||||||
struct wlr_keyboard *wlr_keyboard = wlr_keyboard_from_input_device(device);
|
struct wlr_keyboard *wlr_keyboard = wlr_keyboard_from_input_device(
|
||||||
|
device);
|
||||||
struct absinthe_keyboard *keyboard = calloc(1, sizeof(*keyboard));
|
struct absinthe_keyboard *keyboard = calloc(1, sizeof(*keyboard));
|
||||||
keyboard->server = server;
|
keyboard->server = server;
|
||||||
keyboard->wlr_keyboard = wlr_keyboard;
|
keyboard->wlr = wlr_keyboard;
|
||||||
|
|
||||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
struct xkb_keymap *keymap = xkb_keymap_new_from_names(context, NULL,
|
||||||
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
wlr_keyboard_set_keymap(wlr_keyboard, keymap);
|
wlr_keyboard_set_keymap(wlr_keyboard, keymap);
|
||||||
xkb_keymap_unref(keymap);
|
xkb_keymap_unref(keymap);
|
||||||
xkb_context_unref(context);
|
xkb_context_unref(context);
|
||||||
wlr_keyboard_set_repeat_info(wlr_keyboard, 25, 600);
|
wlr_keyboard_set_repeat_info(wlr_keyboard, 25, 600);
|
||||||
|
|
||||||
keyboard->modifiers.notify = keyboard_handle_modifiers;
|
LISTEN(keyboard->modifiers, handle_modifiers,
|
||||||
wl_signal_add(&wlr_keyboard->events.modifiers, &keyboard->modifiers);
|
wlr_keyboard->events.modifiers);
|
||||||
keyboard->key.notify = keyboard_handle_key;
|
LISTEN(keyboard->key, handle_key, wlr_keyboard->events.key);
|
||||||
wl_signal_add(&wlr_keyboard->events.key, &keyboard->key);
|
LISTEN(keyboard->destroy, handle_destroy,
|
||||||
keyboard->destroy.notify = keyboard_handle_destroy;
|
wlr_keyboard->base.events.destroy);
|
||||||
wl_signal_add(&device->events.destroy, &keyboard->destroy);
|
|
||||||
|
|
||||||
wlr_seat_set_keyboard(server->seat, wlr_keyboard);
|
wlr_seat_set_keyboard(server->seat, wlr_keyboard);
|
||||||
|
|
||||||
wl_list_insert(&server->keyboards, &keyboard->link);
|
wl_list_insert(&server->keyboards, &keyboard->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void server_new_pointer(struct absinthe_server *server, struct wlr_input_device *device)
|
static void
|
||||||
|
new_pointer(struct absinthe_server *server, struct wlr_input_device *device)
|
||||||
{
|
{
|
||||||
wlr_cursor_attach_input_device(server->cursor, device);
|
wlr_cursor_attach_input_device(server->cursor, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_new_input(struct wl_listener *listener, void *data)
|
void
|
||||||
|
new_input(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct absinthe_server *server = wl_container_of(listener, server, new_input);
|
struct absinthe_server *server = wl_container_of(listener, server,
|
||||||
|
new_input);
|
||||||
struct wlr_input_device *device = data;
|
struct wlr_input_device *device = data;
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||||
server_new_keyboard(server, device);
|
new_keyboard(server, device);
|
||||||
break;
|
break;
|
||||||
case WLR_INPUT_DEVICE_POINTER:
|
case WLR_INPUT_DEVICE_POINTER:
|
||||||
server_new_pointer(server, device);
|
new_pointer(server, device);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <wlr/util/edges.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "focus.h"
|
||||||
|
#include "layout.h"
|
||||||
|
#include "output.h"
|
||||||
|
#include "toplevel.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_map(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
map);
|
||||||
|
|
||||||
|
toplevel->scene_tree = wlr_scene_tree_create(
|
||||||
|
&toplevel->server->scene->tree);
|
||||||
|
toplevel->scene_tree->node.data = toplevel;
|
||||||
|
wlr_scene_node_set_enabled(&toplevel->scene_tree->node,
|
||||||
|
toplevel_is_unmanaged(toplevel));
|
||||||
|
|
||||||
|
toplevel->tiled = true;
|
||||||
|
|
||||||
|
if (toplevel->type != TOPLEVEL_X11 &&
|
||||||
|
wl_resource_get_version(toplevel->xdg->resource) >=
|
||||||
|
XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
||||||
|
wlr_xdg_toplevel_set_tiled(toplevel->xdg,
|
||||||
|
WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
||||||
|
WLR_EDGE_RIGHT);
|
||||||
|
} else {
|
||||||
|
wlr_xdg_toplevel_set_maximized(toplevel->xdg, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (toplevel->type == TOPLEVEL_X11) {
|
||||||
|
toplevel->scene_surface = wlr_scene_subsurface_tree_create(
|
||||||
|
toplevel->scene_tree, toplevel->xw->surface);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
toplevel->scene_surface = wlr_scene_xdg_surface_create(
|
||||||
|
toplevel->scene_tree, toplevel->xdg->base);
|
||||||
|
}
|
||||||
|
toplevel->scene_surface->node.data = toplevel;
|
||||||
|
|
||||||
|
toplevel_update_geom(toplevel);
|
||||||
|
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 : TOPLEVEL_BW;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
toplevel->border[i] = wlr_scene_rect_create(
|
||||||
|
toplevel->scene_tree, 0, 0, unfocused_bc);
|
||||||
|
toplevel->border[i]->node.data = toplevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_focused_output(toplevel->server);
|
||||||
|
toplevel->output = toplevel->server->focused_output;
|
||||||
|
toplevel->fullscreen = false;
|
||||||
|
|
||||||
|
wl_list_insert(&toplevel->server->toplevels, &toplevel->link);
|
||||||
|
wl_list_insert(&toplevel->server->focus_stack, &toplevel->flink);
|
||||||
|
|
||||||
|
layout_arrange(toplevel->output);
|
||||||
|
focus_toplevel(focus_get_topmost(toplevel->server));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_unmap(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
unmap);
|
||||||
|
|
||||||
|
if (toplevel == toplevel->server->focused_toplevel) {
|
||||||
|
toplevel->server->focused_toplevel = NULL;
|
||||||
|
toplevel->server->seat->keyboard_state.focused_surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_remove(&toplevel->link);
|
||||||
|
wl_list_remove(&toplevel->flink);
|
||||||
|
|
||||||
|
layout_arrange(toplevel->output);
|
||||||
|
focus_toplevel(focus_get_topmost(toplevel->server));
|
||||||
|
|
||||||
|
wlr_scene_node_destroy(&toplevel->scene_tree->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
destroy);
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (toplevel->type == TOPLEVEL_X11) {
|
||||||
|
wl_list_remove(&toplevel->xw_activate.link);
|
||||||
|
wl_list_remove(&toplevel->xw_associate.link);
|
||||||
|
wl_list_remove(&toplevel->xw_dissociate.link);
|
||||||
|
wl_list_remove(&toplevel->xw_configure.link);
|
||||||
|
wl_list_remove(&toplevel->xw_set_hints.link);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
wl_list_remove(&toplevel->map.link);
|
||||||
|
wl_list_remove(&toplevel->unmap.link);
|
||||||
|
wl_list_remove(&toplevel->commit.link);
|
||||||
|
wl_list_remove(&toplevel->request_move.link);
|
||||||
|
wl_list_remove(&toplevel->request_resize.link);
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_remove(&toplevel->destroy.link);
|
||||||
|
wl_list_remove(&toplevel->request_maximize.link);
|
||||||
|
wl_list_remove(&toplevel->request_fullscreen.link);
|
||||||
|
|
||||||
|
free(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_request_move(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
request_move);
|
||||||
|
if (toplevel->xdg->base->initialized)
|
||||||
|
wlr_xdg_surface_schedule_configure(toplevel->xdg->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_request_resize(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
request_resize);
|
||||||
|
if (toplevel->xdg->base->initialized)
|
||||||
|
wlr_xdg_surface_schedule_configure(toplevel->xdg->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_request_maximize(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
request_maximize);
|
||||||
|
if (toplevel->xdg->base->initialized)
|
||||||
|
wlr_xdg_surface_schedule_configure(toplevel->xdg->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
UNUSED(data);
|
||||||
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
request_fullscreen);
|
||||||
|
toplevel_set_fullscreen(toplevel, toplevel->xdg->requested.fullscreen);
|
||||||
|
}
|
||||||
+186
@@ -0,0 +1,186 @@
|
|||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "toplevel.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "xdg-shell-protocol.h"
|
||||||
|
|
||||||
|
struct absinthe_toplevel *
|
||||||
|
toplevel_at(struct absinthe_server *server, double lx, double ly,
|
||||||
|
struct wlr_surface **surface, double *sx, double *sy)
|
||||||
|
{
|
||||||
|
struct wlr_scene_node *node =
|
||||||
|
wlr_scene_node_at(&server->scene->tree.node, lx, ly, sx, sy);
|
||||||
|
if (!node) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (node->type) {
|
||||||
|
case WLR_SCENE_NODE_BUFFER:
|
||||||
|
struct wlr_scene_buffer *scene_buffer =
|
||||||
|
wlr_scene_buffer_from_node(node);
|
||||||
|
struct wlr_scene_surface *scene_surface =
|
||||||
|
wlr_scene_surface_try_from_buffer(scene_buffer);
|
||||||
|
if (!scene_surface) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*surface = scene_surface->surface;
|
||||||
|
struct wlr_scene_tree *tree = node->parent;
|
||||||
|
while (tree != NULL && tree->node.data == NULL) {
|
||||||
|
tree = tree->node.parent;
|
||||||
|
}
|
||||||
|
return tree->node.data;
|
||||||
|
break;
|
||||||
|
case WLR_SCENE_NODE_RECT:
|
||||||
|
return node->data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
toplevel_is_unmanaged(struct absinthe_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (toplevel->type == TOPLEVEL_X11)
|
||||||
|
return toplevel->xw->override_redirect;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_update_geom(struct absinthe_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (toplevel->type == TOPLEVEL_X11) {
|
||||||
|
toplevel->geom.x = toplevel->xw->x;
|
||||||
|
toplevel->geom.y = toplevel->xw->y;
|
||||||
|
toplevel->geom.width = toplevel->xw->width;
|
||||||
|
toplevel->geom.height = toplevel->xw->height;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
toplevel->geom = toplevel->xdg->base->geometry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_update_borders_geom(struct absinthe_toplevel *toplevel)
|
||||||
|
{
|
||||||
|
int32_t bw = toplevel->bw;
|
||||||
|
|
||||||
|
if (toplevel->geom.width - 2 * bw < 0 ||
|
||||||
|
toplevel->geom.height - 2 * bw < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&toplevel->scene_tree->node,
|
||||||
|
toplevel->geom.x, toplevel->geom.y);
|
||||||
|
wlr_scene_node_set_position(&toplevel->scene_surface->node, bw, bw);
|
||||||
|
|
||||||
|
wlr_scene_rect_set_size(toplevel->border[0],
|
||||||
|
toplevel->geom.width - 2 * bw, bw);
|
||||||
|
wlr_scene_rect_set_size(toplevel->border[1],
|
||||||
|
toplevel->geom.width - 2 * bw, bw);
|
||||||
|
wlr_scene_rect_set_size(toplevel->border[2], bw, toplevel->geom.height);
|
||||||
|
wlr_scene_rect_set_size(toplevel->border[3], bw, toplevel->geom.height);
|
||||||
|
|
||||||
|
wlr_scene_node_set_position(&toplevel->border[0]->node, bw, 0);
|
||||||
|
wlr_scene_node_set_position(&toplevel->border[1]->node, bw,
|
||||||
|
toplevel->geom.height - bw);
|
||||||
|
wlr_scene_node_set_position(&toplevel->border[2]->node, 0, 0);
|
||||||
|
wlr_scene_node_set_position(&toplevel->border[3]->node,
|
||||||
|
toplevel->geom.width - bw, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_set_pos(struct absinthe_toplevel *toplevel, int32_t x, int32_t y)
|
||||||
|
{
|
||||||
|
toplevel->geom.x = x;
|
||||||
|
toplevel->geom.y = y;
|
||||||
|
wlr_scene_node_set_position(&toplevel->scene_tree->node, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_set_size(struct absinthe_toplevel *toplevel, int32_t width,
|
||||||
|
int32_t height)
|
||||||
|
{
|
||||||
|
if (width <= 2 * toplevel->bw || height <= 2 * toplevel->bw ||
|
||||||
|
(width == toplevel->geom.width && height == toplevel->geom.height))
|
||||||
|
return;
|
||||||
|
toplevel->geom.width = width;
|
||||||
|
toplevel->geom.height = height;
|
||||||
|
|
||||||
|
toplevel_update_borders_geom(toplevel);
|
||||||
|
|
||||||
|
struct wlr_box clip = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = width - toplevel->bw,
|
||||||
|
.height = height - toplevel->bw,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (toplevel->type == TOPLEVEL_XDG) {
|
||||||
|
if (wl_resource_get_version(toplevel->xdg->resource) >=
|
||||||
|
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION)
|
||||||
|
wlr_xdg_toplevel_set_bounds(toplevel->xdg, width,
|
||||||
|
height);
|
||||||
|
toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->xdg,
|
||||||
|
width - 2 * toplevel->bw, height - 2 * toplevel->bw);
|
||||||
|
// clip.x = toplevel->xdg->base->geometry.x;
|
||||||
|
// clip.y = toplevel->xdg->base->geometry.y;
|
||||||
|
}
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
else if (toplevel->type == TOPLEVEL_X11) {
|
||||||
|
wlr_xwayland_surface_configure(toplevel->xw, toplevel->geom.x,
|
||||||
|
toplevel->geom.y, width - 2 * toplevel->bw,
|
||||||
|
height - 2 * toplevel->bw);
|
||||||
|
/* manually update position */
|
||||||
|
toplevel_set_pos(toplevel, toplevel->geom.x, toplevel->geom.y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node,
|
||||||
|
&clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_set_fullscreen(struct absinthe_toplevel *toplevel, bool fullscreen)
|
||||||
|
{
|
||||||
|
if (!toplevel || toplevel->fullscreen == fullscreen)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct absinthe_output *output = toplevel->server->focused_output;
|
||||||
|
toplevel->fullscreen = fullscreen;
|
||||||
|
wlr_xdg_toplevel_set_fullscreen(toplevel->xdg, fullscreen);
|
||||||
|
|
||||||
|
if (fullscreen) {
|
||||||
|
toplevel->prev_geom = toplevel->geom;
|
||||||
|
toplevel->bw = 0;
|
||||||
|
toplevel_set_size(toplevel, output->geom.width,
|
||||||
|
output->geom.height);
|
||||||
|
toplevel_set_pos(toplevel, output->geom.x, output->geom.y);
|
||||||
|
} else {
|
||||||
|
toplevel->bw = toplevel_is_unmanaged(toplevel) ? 0 :
|
||||||
|
TOPLEVEL_BW;
|
||||||
|
toplevel_set_size(toplevel, toplevel->prev_geom.width,
|
||||||
|
toplevel->prev_geom.height);
|
||||||
|
toplevel_set_pos(toplevel, toplevel->prev_geom.x,
|
||||||
|
toplevel->prev_geom.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_update_borders_geom(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toplevel_set_border_color(struct absinthe_toplevel *toplevel,
|
||||||
|
const float color[4])
|
||||||
|
{
|
||||||
|
if (!toplevel)
|
||||||
|
return;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
wlr_scene_rect_set_color(toplevel->border[i], color);
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
-8
@@ -2,20 +2,24 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void xdg_decoration_request_mode(struct wl_listener *listener, void *data)
|
void
|
||||||
|
deco_request_mode(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_request_mode);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
if (toplevel->xdg_toplevel->base->initialized)
|
deco_request_mode);
|
||||||
wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->decoration,
|
if (toplevel->xdg->base->initialized)
|
||||||
|
wlr_xdg_toplevel_decoration_v1_set_mode(toplevel->deco,
|
||||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdg_decoration_destroy(struct wl_listener *listener, void *data)
|
void
|
||||||
|
deco_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, decoration_destroy);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
deco_destroy);
|
||||||
|
|
||||||
wl_list_remove(&toplevel->decoration_request_mode.link);
|
wl_list_remove(&toplevel->deco_request_mode.link);
|
||||||
wl_list_remove(&toplevel->decoration_destroy.link);
|
wl_list_remove(&toplevel->deco_destroy.link);
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-5
@@ -3,19 +3,22 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void xdg_popup_commit(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xdg_popup_commit(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_popup *popup = wl_container_of(listener, popup, commit);
|
struct absinthe_popup *popup = wl_container_of(listener, popup, commit);
|
||||||
|
|
||||||
if (popup->xdg_popup->base->initial_commit)
|
if (popup->wlr->base->initial_commit)
|
||||||
wlr_xdg_surface_schedule_configure(popup->xdg_popup->base);
|
wlr_xdg_surface_schedule_configure(popup->wlr->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdg_popup_destroy(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xdg_popup_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_popup *popup = wl_container_of(listener, popup, destroy);
|
struct absinthe_popup *popup = wl_container_of(listener, popup,
|
||||||
|
destroy);
|
||||||
|
|
||||||
wl_list_remove(&popup->commit.link);
|
wl_list_remove(&popup->commit.link);
|
||||||
wl_list_remove(&popup->destroy.link);
|
wl_list_remove(&popup->destroy.link);
|
||||||
|
|||||||
+27
-13
@@ -1,29 +1,43 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "layout.h"
|
|
||||||
#include "output.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "xdg-decoration.h"
|
#include "xdg-decoration.h"
|
||||||
|
|
||||||
void xdg_toplevel_commit(struct wl_listener *listener, void *data)
|
void
|
||||||
|
toplevel_commit(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, commit);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
commit);
|
||||||
|
|
||||||
if (toplevel->xdg_toplevel->base->initial_commit) {
|
if (toplevel->xdg->base->initial_commit) {
|
||||||
wlr_xdg_toplevel_set_activated(toplevel->xdg_toplevel, false);
|
wlr_xdg_toplevel_set_activated(toplevel->xdg, false);
|
||||||
|
|
||||||
/* Forse server side decoration mode */
|
/* forse server side decoration mode */
|
||||||
if (toplevel->decoration)
|
if (toplevel->deco)
|
||||||
xdg_decoration_request_mode(&toplevel->decoration_request_mode, toplevel->decoration);
|
deco_request_mode(&toplevel->deco_request_mode,
|
||||||
toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->xdg_toplevel, 0, 0);
|
toplevel->deco);
|
||||||
|
/* let client set initial size */
|
||||||
|
toplevel->resizing = wlr_xdg_toplevel_set_size(toplevel->xdg, 0,
|
||||||
|
0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toplevel->resizing && toplevel->resizing <= toplevel->xdg_toplevel->base->current.configure_serial)
|
bool resizing = toplevel->resizing &&
|
||||||
|
toplevel->resizing <= toplevel->xdg->base->current.configure_serial;
|
||||||
|
|
||||||
|
/* remove pending resize */
|
||||||
|
if (resizing)
|
||||||
toplevel->resizing = 0;
|
toplevel->resizing = 0;
|
||||||
|
|
||||||
|
struct wlr_box clip = {
|
||||||
|
.x = toplevel->xdg->base->geometry.x,
|
||||||
|
.y = toplevel->xdg->base->geometry.y,
|
||||||
|
.width = toplevel->geom.width - toplevel->bw,
|
||||||
|
.height = toplevel->geom.height - toplevel->bw,
|
||||||
|
};
|
||||||
|
wlr_scene_subsurface_tree_set_clip(&toplevel->scene_surface->node,
|
||||||
|
&clip);
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-26
@@ -1,61 +1,69 @@
|
|||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
|
|
||||||
#include "xwayland.h"
|
#include "toplevel-handlers.h"
|
||||||
#include "absinthe-toplevel-handlers.h"
|
#include "toplevel.h"
|
||||||
#include "absinthe-toplevel.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "xdg-toplevel.h"
|
#include "xwayland.h"
|
||||||
|
|
||||||
void xwayland_activate(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_activate(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, xwayland_activate);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
xw_activate);
|
||||||
|
|
||||||
if (!absinthe_toplevel_is_unmanaged(toplevel))
|
if (!toplevel_is_unmanaged(toplevel))
|
||||||
wlr_xwayland_surface_activate(toplevel->xwayland_surface, 1);
|
wlr_xwayland_surface_activate(toplevel->xw, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xwayland_associate(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_associate(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, xwayland_associate);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
xw_associate);
|
||||||
|
|
||||||
toplevel->map.notify = absinthe_toplevel_map;
|
LISTEN(toplevel->map, toplevel_map, toplevel->xw->surface->events.map);
|
||||||
wl_signal_add(&toplevel->xwayland_surface->surface->events.map, &toplevel->map);
|
LISTEN(toplevel->unmap, toplevel_unmap,
|
||||||
toplevel->unmap.notify = absinthe_toplevel_unmap;
|
toplevel->xw->surface->events.unmap);
|
||||||
wl_signal_add(&toplevel->xwayland_surface->surface->events.unmap, &toplevel->unmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xwayland_dissociate(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_dissociate(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, xwayland_dissociate);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
xw_dissociate);
|
||||||
|
|
||||||
wl_list_remove(&toplevel->map.link);
|
wl_list_remove(&toplevel->map.link);
|
||||||
wl_list_remove(&toplevel->unmap.link);
|
wl_list_remove(&toplevel->unmap.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xwayland_configure(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_configure(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, xwayland_configure);
|
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel,
|
||||||
|
xw_configure);
|
||||||
struct wlr_xwayland_surface_configure_event *event = data;
|
struct wlr_xwayland_surface_configure_event *event = data;
|
||||||
|
|
||||||
if (!toplevel->xwayland_surface->surface || !toplevel->xwayland_surface->surface->mapped) {
|
if (!toplevel->xw->surface || !toplevel->xw->surface->mapped) {
|
||||||
wlr_xwayland_surface_configure(toplevel->xwayland_surface, event->x, event->y, event->width,
|
wlr_xwayland_surface_configure(toplevel->xw, event->x, event->y,
|
||||||
event->height);
|
event->width, event->height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (absinthe_toplevel_is_unmanaged(toplevel)) {
|
if (toplevel_is_unmanaged(toplevel)) {
|
||||||
wlr_scene_node_set_position(&toplevel->scene_tree->node, event->x, event->y);
|
wlr_scene_node_set_position(&toplevel->scene_tree->node,
|
||||||
wlr_xwayland_surface_configure(toplevel->xwayland_surface, event->x, event->y, event->width,
|
event->x, event->y);
|
||||||
event->height);
|
wlr_xwayland_surface_configure(toplevel->xw, event->x, event->y,
|
||||||
|
event->width, event->height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xwayland_set_hints(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_set_hints(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
UNUSED(listener);
|
UNUSED(listener);
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
|
|||||||
Reference in New Issue
Block a user