mirror of
https://github.com/labwc/labwc.git
synced 2025-10-31 22:25:34 -04:00
Update .clang-format
Align with wlroots style
This commit is contained in:
parent
96b5ab1fc1
commit
96e05057a3
32 changed files with 669 additions and 515 deletions
130
.clang-format
130
.clang-format
|
|
@ -1,167 +1,41 @@
|
||||||
# Copied from https://github.com/git/git/blob/master/.clang-format
|
|
||||||
# under GPL-2.0.
|
|
||||||
|
|
||||||
UseTab: Always
|
UseTab: Always
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
IndentWidth: 8
|
IndentWidth: 8
|
||||||
ContinuationIndentWidth: 8
|
ContinuationIndentWidth: 8
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
|
|
||||||
# C Language specifics
|
|
||||||
Language: Cpp
|
|
||||||
|
|
||||||
# Align parameters on the open bracket
|
|
||||||
# someLongFunction(argument1,
|
|
||||||
# argument2);
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
|
|
||||||
# Don't align consecutive assignments
|
|
||||||
# int aaaa = 12;
|
|
||||||
# int b = 14;
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
|
|
||||||
# Don't align consecutive declarations
|
|
||||||
# int aaaa = 12;
|
|
||||||
# double b = 3.14;
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
|
|
||||||
# Align escaped newlines as far left as possible
|
|
||||||
# #define A \
|
|
||||||
# int aaaa; \
|
|
||||||
# int b; \
|
|
||||||
# int cccccccc;
|
|
||||||
AlignEscapedNewlines: Left
|
|
||||||
|
|
||||||
# Align operands of binary and ternary expressions
|
|
||||||
# int aaa = bbbbbbbbbbb +
|
|
||||||
# cccccc;
|
|
||||||
AlignOperands: true
|
AlignOperands: true
|
||||||
|
|
||||||
# Don't align trailing comments
|
|
||||||
# int a; // Comment a
|
|
||||||
# int b = 2; // Comment b
|
|
||||||
AlignTrailingComments: false
|
|
||||||
|
|
||||||
# By default don't allow putting parameters onto the next line
|
|
||||||
# myFunction(foo, bar, baz);
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
|
||||||
# Don't allow short braced statements to be on a single line
|
|
||||||
# if (a) not if (a) return;
|
|
||||||
# return;
|
|
||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortBlocksOnASingleLine: false
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: false
|
AllowShortFunctionsOnASingleLine: false
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||||
# By default don't add a line break after the return type of top-level functions
|
|
||||||
# int foo();
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
|
|
||||||
# Pack as many parameters or arguments onto the same line as possible
|
|
||||||
# int myFunction(int aaaaaaaaaaaa, int bbbbbbbb,
|
|
||||||
# int cccc);
|
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
BinPackParameters: true
|
BinPackParameters: true
|
||||||
|
|
||||||
# Attach braces to surrounding context except break before braces on function
|
|
||||||
# definitions.
|
|
||||||
# void foo()
|
|
||||||
# {
|
|
||||||
# if (true) {
|
|
||||||
# } else {
|
|
||||||
# }
|
|
||||||
# };
|
|
||||||
BreakBeforeBraces: Linux
|
BreakBeforeBraces: Linux
|
||||||
|
|
||||||
# Break after operators
|
# Break after operators
|
||||||
# int valuve = aaaaaaaaaaaaa +
|
|
||||||
# bbbbbb -
|
|
||||||
# ccccccccccc;
|
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeTernaryOperators: false
|
BreakBeforeTernaryOperators: false
|
||||||
|
|
||||||
# Don't break string literals
|
|
||||||
BreakStringLiterals: false
|
BreakStringLiterals: false
|
||||||
|
|
||||||
# Use the same indentation level as for the switch statement.
|
|
||||||
# Switch statement body is always indented one level more than case labels.
|
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
|
|
||||||
# Don't indent a function definition or declaration if it is wrapped after the
|
|
||||||
# type
|
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
|
|
||||||
# Align pointer to the right
|
|
||||||
# int *a;
|
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
|
|
||||||
# Don't insert a space after a cast
|
|
||||||
# x = (int32)y; not x = (int32) y;
|
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
|
|
||||||
# Insert spaces before and after assignment operators
|
|
||||||
# int a = 5; not int a=5;
|
|
||||||
# a += 42; a+=42;
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
|
||||||
# Put a space before opening parentheses only after control statement keywords.
|
|
||||||
# void f() {
|
|
||||||
# if (true) {
|
|
||||||
# f();
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
|
|
||||||
# Don't insert spaces inside empty '()'
|
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
|
|
||||||
# The number of spaces before trailing line comments (// - comments).
|
|
||||||
# This does not affect trailing block comments (/* - comments).
|
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
|
|
||||||
# Don't insert spaces in casts
|
|
||||||
# x = (int32) y; not x = ( int32 ) y;
|
|
||||||
SpacesInCStyleCastParentheses: false
|
SpacesInCStyleCastParentheses: false
|
||||||
|
|
||||||
# Don't insert spaces inside container literals
|
|
||||||
# var arr = [1, 2, 3]; not var arr = [ 1, 2, 3 ];
|
|
||||||
SpacesInContainerLiterals: false
|
SpacesInContainerLiterals: false
|
||||||
|
|
||||||
# Don't insert spaces after '(' or before ')'
|
|
||||||
# f(arg); not f( arg );
|
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
|
|
||||||
# Don't insert spaces after '[' or before ']'
|
|
||||||
# int a[5]; not int a[ 5 ];
|
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
|
|
||||||
# Insert a space after '{' and before '}' in struct initializers
|
|
||||||
Cpp11BracedListStyle: false
|
Cpp11BracedListStyle: false
|
||||||
|
|
||||||
# A list of macros that should be interpreted as foreach loops instead of as
|
|
||||||
# function calls.
|
|
||||||
ForEachMacros:
|
ForEachMacros:
|
||||||
- 'wl_list_for_each'
|
- 'wl_list_for_each'
|
||||||
- 'wl_list_for_each_reverse'
|
- 'wl_list_for_each_reverse'
|
||||||
- 'wl_list_for_each_safe'
|
- 'wl_list_for_each_safe'
|
||||||
|
|
||||||
# The maximum number of consecutive empty lines to keep.
|
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
|
|
||||||
# No empty line at the start of a block.
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
SortIncludes: true
|
||||||
# Penalties
|
|
||||||
# This decides what order things should be done if a line is too long
|
|
||||||
PenaltyBreakAssignment: 10
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 30
|
|
||||||
PenaltyBreakComment: 10
|
|
||||||
PenaltyBreakFirstLessLess: 0
|
|
||||||
PenaltyBreakString: 10
|
|
||||||
PenaltyExcessCharacter: 100
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
|
||||||
|
|
||||||
# Don't sort #include's
|
|
||||||
SortIncludes: false
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef __LABWC_RCXML_H
|
#ifndef __LABWC_RCXML_H
|
||||||
#define __LABWC_RCXML_H
|
#define __LABWC_RCXML_H
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
#include "common/buf.h"
|
#include "common/buf.h"
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_cursor.h>
|
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
#include <wlr/types/wlr_cursor.h>
|
||||||
#include <wlr/types/wlr_data_device.h>
|
#include <wlr/types/wlr_data_device.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
#include <wlr/types/wlr_input_device.h>
|
||||||
#include <wlr/types/wlr_keyboard.h>
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
|
|
@ -20,18 +20,18 @@
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_pointer.h>
|
#include <wlr/types/wlr_pointer.h>
|
||||||
#include <wlr/types/wlr_seat.h>
|
#include <wlr/types/wlr_seat.h>
|
||||||
#include <wlr/types/wlr_xcursor_manager.h>
|
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
|
#include <wlr/types/wlr_xcursor_manager.h>
|
||||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||||
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include "common/bug-on.h"
|
#include "common/bug-on.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "config/rcxml.h"
|
|
||||||
#include "config/keybind.h"
|
#include "config/keybind.h"
|
||||||
|
#include "config/rcxml.h"
|
||||||
|
|
||||||
#define XCURSOR_DEFAULT "left_ptr"
|
#define XCURSOR_DEFAULT "left_ptr"
|
||||||
#define XCURSOR_SIZE 24
|
#define XCURSOR_SIZE 24
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
#ifndef __LABWC_PARSE_H
|
#ifndef __LABWC_PARSE_H
|
||||||
#define __LABWC_PARSE_H
|
#define __LABWC_PARSE_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "xbm/tokenize.h"
|
#include "xbm/tokenize.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct pixmap {
|
struct pixmap {
|
||||||
uint32_t *data;
|
uint32_t *data;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include "common/spawn.h"
|
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
#include "common/spawn.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
static void reconfigure(void)
|
static void
|
||||||
|
reconfigure(void)
|
||||||
{
|
{
|
||||||
char *const args[] = { "killall", "-SIGHUP", "labwc", NULL };
|
char *const args[] = { "killall", "-SIGHUP", "labwc", NULL };
|
||||||
execvp(args[0], args);
|
execvp(args[0], args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action(struct server *server, const char *action, const char *command)
|
void
|
||||||
|
action(struct server *server, const char *action, const char *command)
|
||||||
{
|
{
|
||||||
if (!action)
|
if (!action)
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "common/buf.h"
|
#include "common/buf.h"
|
||||||
|
|
||||||
void buf_init(struct buf *s)
|
void
|
||||||
|
buf_init(struct buf *s)
|
||||||
{
|
{
|
||||||
s->alloc = 256;
|
s->alloc = 256;
|
||||||
s->buf = malloc(s->alloc);
|
s->buf = malloc(s->alloc);
|
||||||
|
|
@ -8,10 +9,12 @@ void buf_init(struct buf *s)
|
||||||
s->len = 0;
|
s->len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buf_add(struct buf *s, const char *data)
|
void
|
||||||
|
buf_add(struct buf *s, const char *data)
|
||||||
{
|
{
|
||||||
if (!data || data[0] == '\0')
|
if (!data || data[0] == '\0') {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
int len = strlen(data);
|
int len = strlen(data);
|
||||||
if (s->alloc <= s->len + len + 1) {
|
if (s->alloc <= s->len + len + 1) {
|
||||||
s->alloc = s->alloc + len;
|
s->alloc = s->alloc + len;
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@
|
||||||
* Copyright Johan Malm 2020
|
* Copyright Johan Malm 2020
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include "common/dir.h"
|
#include "common/dir.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
|
@ -39,7 +39,8 @@ static struct dir theme_dirs[] = {
|
||||||
};
|
};
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
static bool isdir(const char *path)
|
static bool
|
||||||
|
isdir(const char *path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
return (!stat(path, &st) && S_ISDIR(st.st_mode));
|
return (!stat(path, &st) && S_ISDIR(st.st_mode));
|
||||||
|
|
@ -53,25 +54,30 @@ struct ctx {
|
||||||
const char *theme_name;
|
const char *theme_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void build_config_path(struct ctx *ctx, char *prefix, const char *path)
|
static void
|
||||||
|
build_config_path(struct ctx *ctx, char *prefix, const char *path)
|
||||||
{
|
{
|
||||||
if (!prefix)
|
if (!prefix) {
|
||||||
snprintf(ctx->buf, ctx->len, "%s", path);
|
snprintf(ctx->buf, ctx->len, "%s", path);
|
||||||
else
|
} else {
|
||||||
snprintf(ctx->buf, ctx->len, "%s/%s", prefix, path);
|
snprintf(ctx->buf, ctx->len, "%s/%s", prefix, path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_theme_path(struct ctx *ctx, char *prefix, const char *path)
|
static void
|
||||||
|
build_theme_path(struct ctx *ctx, char *prefix, const char *path)
|
||||||
{
|
{
|
||||||
if (!prefix)
|
if (!prefix) {
|
||||||
snprintf(ctx->buf, ctx->len, "%s/%s/openbox-3", path,
|
snprintf(ctx->buf, ctx->len, "%s/%s/openbox-3", path,
|
||||||
ctx->theme_name);
|
ctx->theme_name);
|
||||||
else
|
} else {
|
||||||
snprintf(ctx->buf, ctx->len, "%s/%s/%s/openbox-3", prefix, path,
|
snprintf(ctx->buf, ctx->len, "%s/%s/%s/openbox-3", prefix, path,
|
||||||
ctx->theme_name);
|
ctx->theme_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *find_dir(struct ctx *ctx)
|
char *
|
||||||
|
find_dir(struct ctx *ctx)
|
||||||
{
|
{
|
||||||
char *debug = getenv("LABWC_DEBUG_DIR_CONFIG_AND_THEME");
|
char *debug = getenv("LABWC_DEBUG_DIR_CONFIG_AND_THEME");
|
||||||
|
|
||||||
|
|
@ -80,20 +86,24 @@ char *find_dir(struct ctx *ctx)
|
||||||
if (!d.prefix) {
|
if (!d.prefix) {
|
||||||
/* handle /etc/xdg... */
|
/* handle /etc/xdg... */
|
||||||
ctx->build_path_fn(ctx, NULL, d.path);
|
ctx->build_path_fn(ctx, NULL, d.path);
|
||||||
if (debug)
|
if (debug) {
|
||||||
info("%s", ctx->buf);
|
info("%s", ctx->buf);
|
||||||
if (isdir(ctx->buf))
|
}
|
||||||
|
if (isdir(ctx->buf)) {
|
||||||
return ctx->buf;
|
return ctx->buf;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* handle $HOME/.config/... and $XDG_* */
|
/* handle $HOME/.config/... and $XDG_* */
|
||||||
char *prefix = getenv(d.prefix);
|
char *prefix = getenv(d.prefix);
|
||||||
if (!prefix)
|
if (!prefix) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
gchar **prefixes = g_strsplit(prefix, ":", -1);
|
gchar **prefixes = g_strsplit(prefix, ":", -1);
|
||||||
for (gchar **p = prefixes; *p; p++) {
|
for (gchar **p = prefixes; *p; p++) {
|
||||||
ctx->build_path_fn(ctx, *p, d.path);
|
ctx->build_path_fn(ctx, *p, d.path);
|
||||||
if (debug)
|
if (debug) {
|
||||||
info("%s", ctx->buf);
|
info("%s", ctx->buf);
|
||||||
|
}
|
||||||
if (isdir(ctx->buf)) {
|
if (isdir(ctx->buf)) {
|
||||||
g_strfreev(prefixes);
|
g_strfreev(prefixes);
|
||||||
return ctx->buf;
|
return ctx->buf;
|
||||||
|
|
@ -107,11 +117,13 @@ char *find_dir(struct ctx *ctx)
|
||||||
return ctx->buf;
|
return ctx->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *config_dir(void)
|
char *
|
||||||
|
config_dir(void)
|
||||||
{
|
{
|
||||||
static char buf[4096] = { 0 };
|
static char buf[4096] = { 0 };
|
||||||
if (buf[0] != '\0')
|
if (buf[0] != '\0') {
|
||||||
return buf;
|
return buf;
|
||||||
|
}
|
||||||
struct ctx ctx = { .build_path_fn = build_config_path,
|
struct ctx ctx = { .build_path_fn = build_config_path,
|
||||||
.buf = buf,
|
.buf = buf,
|
||||||
.len = sizeof(buf),
|
.len = sizeof(buf),
|
||||||
|
|
@ -119,7 +131,8 @@ char *config_dir(void)
|
||||||
return find_dir(&ctx);
|
return find_dir(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *theme_dir(const char *theme_name)
|
char *
|
||||||
|
theme_dir(const char *theme_name)
|
||||||
{
|
{
|
||||||
static char buf[4096] = { 0 };
|
static char buf[4096] = { 0 };
|
||||||
struct ctx ctx = { .build_path_fn = build_theme_path,
|
struct ctx ctx = { .build_path_fn = build_theme_path,
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include "common/font.h"
|
#include "common/font.h"
|
||||||
|
|
||||||
static PangoRectangle font_extents(const char *font_description,
|
static PangoRectangle
|
||||||
const char *string)
|
font_extents(const char *font_description, const char *string)
|
||||||
{
|
{
|
||||||
PangoRectangle rect;
|
PangoRectangle rect;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
|
@ -35,7 +35,8 @@ static PangoRectangle font_extents(const char *font_description,
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
int font_height(const char *font_description)
|
int
|
||||||
|
font_height(const char *font_description)
|
||||||
{
|
{
|
||||||
PangoRectangle rectangle;
|
PangoRectangle rectangle;
|
||||||
rectangle = font_extents(font_description, "abcdefg");
|
rectangle = font_extents(font_description, "abcdefg");
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,22 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
char *grab_file(const char *filename)
|
char *
|
||||||
|
grab_file(const char *filename)
|
||||||
{
|
{
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
FILE *stream = fopen(filename, "r");
|
FILE *stream = fopen(filename, "r");
|
||||||
if (!stream)
|
if (!stream) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
struct buf buffer;
|
struct buf buffer;
|
||||||
buf_init(&buffer);
|
buf_init(&buffer);
|
||||||
while ((getline(&line, &len, stream) != -1)) {
|
while ((getline(&line, &len, stream) != -1)) {
|
||||||
char *p = strrchr(line, '\n');
|
char *p = strrchr(line, '\n');
|
||||||
if (p)
|
if (p) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
}
|
||||||
buf_add(&buffer, line);
|
buf_add(&buffer, line);
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define LABWC_COLOR_YELLOW "\033[0;33m"
|
#define LABWC_COLOR_YELLOW "\033[0;33m"
|
||||||
#define LABWC_COLOR_RED "\033[0;31m"
|
#define LABWC_COLOR_RED "\033[0;31m"
|
||||||
#define LABWC_COLOR_RESET "\033[0m"
|
#define LABWC_COLOR_RESET "\033[0m"
|
||||||
|
|
||||||
void info(const char *msg, ...)
|
void
|
||||||
|
info(const char *msg, ...)
|
||||||
{
|
{
|
||||||
va_list params;
|
va_list params;
|
||||||
fprintf(stderr, LABWC_COLOR_YELLOW);
|
fprintf(stderr, LABWC_COLOR_YELLOW);
|
||||||
|
|
@ -19,7 +20,8 @@ void info(const char *msg, ...)
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void warn(const char *err, ...)
|
void
|
||||||
|
warn(const char *err, ...)
|
||||||
{
|
{
|
||||||
va_list params;
|
va_list params;
|
||||||
fprintf(stderr, LABWC_COLOR_RED);
|
fprintf(stderr, LABWC_COLOR_RED);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
void spawn_async_no_shell(char const *command)
|
void
|
||||||
|
spawn_async_no_shell(char const *command)
|
||||||
{
|
{
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
gchar **argv = NULL;
|
gchar **argv = NULL;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,31 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <glib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
|
#include "common/log.h"
|
||||||
#include "config/keybind.h"
|
#include "config/keybind.h"
|
||||||
#include "config/rcxml.h"
|
#include "config/rcxml.h"
|
||||||
#include "common/log.h"
|
|
||||||
|
|
||||||
static uint32_t parse_modifier(const char *symname)
|
static uint32_t
|
||||||
|
parse_modifier(const char *symname)
|
||||||
{
|
{
|
||||||
if (!strcmp(symname, "S"))
|
if (!strcmp(symname, "S")) {
|
||||||
return WLR_MODIFIER_SHIFT;
|
return WLR_MODIFIER_SHIFT;
|
||||||
else if (!strcmp(symname, "C"))
|
} else if (!strcmp(symname, "C")) {
|
||||||
return WLR_MODIFIER_CTRL;
|
return WLR_MODIFIER_CTRL;
|
||||||
else if (!strcmp(symname, "A"))
|
} else if (!strcmp(symname, "A")) {
|
||||||
return WLR_MODIFIER_ALT;
|
return WLR_MODIFIER_ALT;
|
||||||
else if (!strcmp(symname, "W"))
|
} else if (!strcmp(symname, "W")) {
|
||||||
return WLR_MODIFIER_LOGO;
|
return WLR_MODIFIER_LOGO;
|
||||||
else
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct keybind *keybind_create(const char *keybind)
|
struct keybind *
|
||||||
|
keybind_create(const char *keybind)
|
||||||
{
|
{
|
||||||
struct keybind *k = calloc(1, sizeof(struct keybind));
|
struct keybind *k = calloc(1, sizeof(struct keybind));
|
||||||
xkb_keysym_t keysyms[32];
|
xkb_keysym_t keysyms[32];
|
||||||
|
|
@ -46,8 +49,9 @@ struct keybind *keybind_create(const char *keybind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_strfreev(symnames);
|
g_strfreev(symnames);
|
||||||
if (!k)
|
if (!k) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
wl_list_insert(&rc.keybinds, &k->link);
|
wl_list_insert(&rc.keybinds, &k->link);
|
||||||
k->keysyms = malloc(k->keysyms_len * sizeof(xkb_keysym_t));
|
k->keysyms = malloc(k->keysyms_len * sizeof(xkb_keysym_t));
|
||||||
memcpy(k->keysyms, keysyms, k->keysyms_len * sizeof(xkb_keysym_t));
|
memcpy(k->keysyms, keysyms, k->keysyms_len * sizeof(xkb_keysym_t));
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <libxml/parser.h>
|
|
||||||
#include <libxml/tree.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
#include "config/rcxml.h"
|
|
||||||
#include "config/keybind.h"
|
|
||||||
#include "common/dir.h"
|
|
||||||
#include "common/bug-on.h"
|
#include "common/bug-on.h"
|
||||||
|
#include "common/dir.h"
|
||||||
#include "common/font.h"
|
#include "common/font.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
#include "config/keybind.h"
|
||||||
|
#include "config/rcxml.h"
|
||||||
|
|
||||||
static bool in_keybind = false;
|
static bool in_keybind = false;
|
||||||
static bool is_attribute = false;
|
static bool is_attribute = false;
|
||||||
|
|
@ -30,21 +30,26 @@ enum font_place {
|
||||||
/* TODO: Add all places based on Openbox's rc.xml */
|
/* TODO: Add all places based on Openbox's rc.xml */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void rstrip(char *buf, const char *pattern)
|
static void
|
||||||
|
rstrip(char *buf, const char *pattern)
|
||||||
{
|
{
|
||||||
char *p = strstr(buf, pattern);
|
char *p = strstr(buf, pattern);
|
||||||
if (!p)
|
if (!p) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_keybind(char *nodename, char *content)
|
static void
|
||||||
|
fill_keybind(char *nodename, char *content)
|
||||||
{
|
{
|
||||||
if (!content)
|
if (!content) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
rstrip(nodename, ".keybind.keyboard");
|
rstrip(nodename, ".keybind.keyboard");
|
||||||
if (!strcmp(nodename, "key"))
|
if (!strcmp(nodename, "key")) {
|
||||||
current_keybind = keybind_create(content);
|
current_keybind = keybind_create(content);
|
||||||
|
}
|
||||||
/* We expect <keybind key=""> to come first */
|
/* We expect <keybind key=""> to come first */
|
||||||
BUG_ON(!current_keybind);
|
BUG_ON(!current_keybind);
|
||||||
if (!strcmp(nodename, "name.action")) {
|
if (!strcmp(nodename, "name.action")) {
|
||||||
|
|
@ -54,56 +59,70 @@ static void fill_keybind(char *nodename, char *content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get_bool(const char *s)
|
static bool
|
||||||
|
get_bool(const char *s)
|
||||||
{
|
{
|
||||||
if (!s)
|
if (!s) {
|
||||||
return false;
|
return false;
|
||||||
if (!strcasecmp(s, "yes"))
|
}
|
||||||
|
if (!strcasecmp(s, "yes")) {
|
||||||
return true;
|
return true;
|
||||||
if (!strcasecmp(s, "true"))
|
}
|
||||||
|
if (!strcasecmp(s, "true")) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_font(char *nodename, char *content, enum font_place place)
|
static void
|
||||||
|
fill_font(char *nodename, char *content, enum font_place place)
|
||||||
{
|
{
|
||||||
if (!content)
|
if (!content) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
rstrip(nodename, ".font.theme");
|
rstrip(nodename, ".font.theme");
|
||||||
|
|
||||||
/* TODO: implement for all font places */
|
/* TODO: implement for all font places */
|
||||||
if (place != FONT_PLACE_ACTIVEWINDOW)
|
if (place != FONT_PLACE_ACTIVEWINDOW) {
|
||||||
return;
|
return;
|
||||||
if (!strcmp(nodename, "name"))
|
}
|
||||||
|
if (!strcmp(nodename, "name")) {
|
||||||
rc.font_name_activewindow = strdup(content);
|
rc.font_name_activewindow = strdup(content);
|
||||||
else if (!strcmp(nodename, "size"))
|
} else if (!strcmp(nodename, "size")) {
|
||||||
rc.font_size_activewindow = atoi(content);
|
rc.font_size_activewindow = atoi(content);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum font_place enum_font_place(const char *place)
|
static enum font_place
|
||||||
|
enum_font_place(const char *place)
|
||||||
{
|
{
|
||||||
if (!place)
|
if (!place) {
|
||||||
return FONT_PLACE_UNKNOWN;
|
return FONT_PLACE_UNKNOWN;
|
||||||
if (!strcasecmp(place, "ActiveWindow"))
|
}
|
||||||
|
if (!strcasecmp(place, "ActiveWindow")) {
|
||||||
return FONT_PLACE_ACTIVEWINDOW;
|
return FONT_PLACE_ACTIVEWINDOW;
|
||||||
else if (!strcasecmp(place, "InactiveWindow"))
|
} else if (!strcasecmp(place, "InactiveWindow")) {
|
||||||
return FONT_PLACE_INACTIVEWINDOW;
|
return FONT_PLACE_INACTIVEWINDOW;
|
||||||
|
}
|
||||||
return FONT_PLACE_UNKNOWN;
|
return FONT_PLACE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void entry(xmlNode *node, char *nodename, char *content)
|
static void
|
||||||
|
entry(xmlNode *node, char *nodename, char *content)
|
||||||
{
|
{
|
||||||
/* current <theme><font place=""></theme> */
|
/* current <theme><font place=""></theme> */
|
||||||
static enum font_place font_place = FONT_PLACE_UNKNOWN;
|
static enum font_place font_place = FONT_PLACE_UNKNOWN;
|
||||||
|
|
||||||
if (!nodename)
|
if (!nodename) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
rstrip(nodename, ".openbox_config");
|
rstrip(nodename, ".openbox_config");
|
||||||
|
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
if (write_to_nodename_buffer) {
|
if (write_to_nodename_buffer) {
|
||||||
if (is_attribute)
|
if (is_attribute) {
|
||||||
buf_add(nodename_buffer, "@");
|
buf_add(nodename_buffer, "@");
|
||||||
|
}
|
||||||
buf_add(nodename_buffer, nodename);
|
buf_add(nodename_buffer, nodename);
|
||||||
if (content) {
|
if (content) {
|
||||||
buf_add(nodename_buffer, ": ");
|
buf_add(nodename_buffer, ": ");
|
||||||
|
|
@ -112,34 +131,41 @@ static void entry(xmlNode *node, char *nodename, char *content)
|
||||||
buf_add(nodename_buffer, "\n");
|
buf_add(nodename_buffer, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!content)
|
if (!content) {
|
||||||
return;
|
return;
|
||||||
if (in_keybind)
|
}
|
||||||
|
if (in_keybind) {
|
||||||
fill_keybind(nodename, content);
|
fill_keybind(nodename, content);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_attribute && !strcmp(nodename, "place.font.theme"))
|
if (is_attribute && !strcmp(nodename, "place.font.theme")) {
|
||||||
font_place = enum_font_place(content);
|
font_place = enum_font_place(content);
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(nodename, "xdg_shell_server_side_deco.lab"))
|
if (!strcmp(nodename, "xdg_shell_server_side_deco.lab")) {
|
||||||
rc.xdg_shell_server_side_deco = get_bool(content);
|
rc.xdg_shell_server_side_deco = get_bool(content);
|
||||||
else if (!strcmp(nodename, "layout.keyboard.lab"))
|
} else if (!strcmp(nodename, "layout.keyboard.lab")) {
|
||||||
setenv("XKB_DEFAULT_LAYOUT", content, 1);
|
setenv("XKB_DEFAULT_LAYOUT", content, 1);
|
||||||
else if (!strcmp(nodename, "name.theme"))
|
} else if (!strcmp(nodename, "name.theme")) {
|
||||||
rc.theme_name = strdup(content);
|
rc.theme_name = strdup(content);
|
||||||
else if (!strcmp(nodename, "name.font.theme"))
|
} else if (!strcmp(nodename, "name.font.theme")) {
|
||||||
fill_font(nodename, content, font_place);
|
fill_font(nodename, content, font_place);
|
||||||
else if (!strcmp(nodename, "size.font.theme"))
|
} else if (!strcmp(nodename, "size.font.theme")) {
|
||||||
fill_font(nodename, content, font_place);
|
fill_font(nodename, content, font_place);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *nodename(xmlNode *node, char *buf, int len)
|
static char *
|
||||||
|
nodename(xmlNode *node, char *buf, int len)
|
||||||
{
|
{
|
||||||
if (!node || !node->name)
|
if (!node || !node->name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ignore superflous 'text.' in node name */
|
/* Ignore superflous 'text.' in node name */
|
||||||
if (node->parent && !strcmp((char *)node->name, "text"))
|
if (node->parent && !strcmp((char *)node->name, "text")) {
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
|
}
|
||||||
|
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
p[--len] = 0;
|
p[--len] = 0;
|
||||||
|
|
@ -153,44 +179,52 @@ static char *nodename(xmlNode *node, char *buf, int len)
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
if (!node || !node->name)
|
if (!node || !node->name) {
|
||||||
return buf;
|
return buf;
|
||||||
|
}
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
if (!--len)
|
if (!--len) {
|
||||||
return buf;
|
return buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_node(xmlNode *node)
|
static void
|
||||||
|
process_node(xmlNode *node)
|
||||||
{
|
{
|
||||||
char *content;
|
char *content;
|
||||||
static char buffer[256];
|
static char buffer[256];
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
content = (char *)node->content;
|
content = (char *)node->content;
|
||||||
if (xmlIsBlankNode(node))
|
if (xmlIsBlankNode(node)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
name = nodename(node, buffer, sizeof(buffer));
|
name = nodename(node, buffer, sizeof(buffer));
|
||||||
entry(node, name, content);
|
entry(node, name, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xml_tree_walk(xmlNode *node);
|
static void xml_tree_walk(xmlNode *node);
|
||||||
|
|
||||||
static void traverse(xmlNode *n)
|
static void
|
||||||
|
traverse(xmlNode *n)
|
||||||
{
|
{
|
||||||
process_node(n);
|
process_node(n);
|
||||||
is_attribute = true;
|
is_attribute = true;
|
||||||
for (xmlAttr *attr = n->properties; attr; attr = attr->next)
|
for (xmlAttr *attr = n->properties; attr; attr = attr->next) {
|
||||||
xml_tree_walk(attr->children);
|
xml_tree_walk(attr->children);
|
||||||
|
}
|
||||||
is_attribute = false;
|
is_attribute = false;
|
||||||
xml_tree_walk(n->children);
|
xml_tree_walk(n->children);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xml_tree_walk(xmlNode *node)
|
static void
|
||||||
|
xml_tree_walk(xmlNode *node)
|
||||||
{
|
{
|
||||||
for (xmlNode *n = node; n && n->name; n = n->next) {
|
for (xmlNode *n = node; n && n->name; n = n->next) {
|
||||||
if (!strcasecmp((char *)n->name, "comment"))
|
if (!strcasecmp((char *)n->name, "comment")) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (!strcasecmp((char *)n->name, "keybind")) {
|
if (!strcasecmp((char *)n->name, "keybind")) {
|
||||||
in_keybind = true;
|
in_keybind = true;
|
||||||
traverse(n);
|
traverse(n);
|
||||||
|
|
@ -202,7 +236,8 @@ static void xml_tree_walk(xmlNode *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exposed in header file to allow unit tests to parse buffers */
|
/* Exposed in header file to allow unit tests to parse buffers */
|
||||||
void rcxml_parse_xml(struct buf *b)
|
void
|
||||||
|
rcxml_parse_xml(struct buf *b)
|
||||||
{
|
{
|
||||||
xmlDoc *d = xmlParseMemory(b->buf, b->len);
|
xmlDoc *d = xmlParseMemory(b->buf, b->len);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
|
|
@ -214,38 +249,47 @@ void rcxml_parse_xml(struct buf *b)
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pre_processing(void)
|
static void
|
||||||
|
pre_processing(void)
|
||||||
{
|
{
|
||||||
rc.xdg_shell_server_side_deco = true;
|
rc.xdg_shell_server_side_deco = true;
|
||||||
rc.font_size_activewindow = 8;
|
rc.font_size_activewindow = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcxml_init()
|
static void
|
||||||
|
rcxml_init()
|
||||||
{
|
{
|
||||||
static bool has_run;
|
static bool has_run;
|
||||||
|
|
||||||
if (has_run)
|
if (has_run) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
has_run = true;
|
has_run = true;
|
||||||
LIBXML_TEST_VERSION
|
LIBXML_TEST_VERSION
|
||||||
wl_list_init(&rc.keybinds);
|
wl_list_init(&rc.keybinds);
|
||||||
pre_processing();
|
pre_processing();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bind(const char *binding, const char *action, const char *command)
|
static void
|
||||||
|
bind(const char *binding, const char *action, const char *command)
|
||||||
{
|
{
|
||||||
if (!binding || !action)
|
if (!binding || !action) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
struct keybind *k = keybind_create(binding);
|
struct keybind *k = keybind_create(binding);
|
||||||
if (!k)
|
if (!k) {
|
||||||
return;
|
return;
|
||||||
if (action)
|
}
|
||||||
|
if (action) {
|
||||||
k->action = strdup(action);
|
k->action = strdup(action);
|
||||||
if (command)
|
}
|
||||||
|
if (command) {
|
||||||
k->command = strdup(command);
|
k->command = strdup(command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_title_height(void)
|
static void
|
||||||
|
set_title_height(void)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
snprintf(buf, sizeof(buf), "%s %d", rc.font_name_activewindow,
|
snprintf(buf, sizeof(buf), "%s %d", rc.font_name_activewindow,
|
||||||
|
|
@ -253,7 +297,8 @@ static void set_title_height(void)
|
||||||
rc.title_height = font_height(buf);
|
rc.title_height = font_height(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void post_processing(void)
|
static void
|
||||||
|
post_processing(void)
|
||||||
{
|
{
|
||||||
if (!wl_list_length(&rc.keybinds)) {
|
if (!wl_list_length(&rc.keybinds)) {
|
||||||
info("loading default key bindings");
|
info("loading default key bindings");
|
||||||
|
|
@ -263,22 +308,26 @@ static void post_processing(void)
|
||||||
bind("A-F3", "Execute", "dmenu_run");
|
bind("A-F3", "Execute", "dmenu_run");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rc.theme_name)
|
if (!rc.theme_name) {
|
||||||
rc.theme_name = strdup("Clearlooks");
|
rc.theme_name = strdup("Clearlooks");
|
||||||
if (!rc.font_name_activewindow)
|
}
|
||||||
|
if (!rc.font_name_activewindow) {
|
||||||
rc.font_name_activewindow = strdup("sans");
|
rc.font_name_activewindow = strdup("sans");
|
||||||
|
}
|
||||||
set_title_height();
|
set_title_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcxml_path(char *buf, size_t len)
|
static void
|
||||||
|
rcxml_path(char *buf, size_t len)
|
||||||
{
|
{
|
||||||
if (!strlen(config_dir()))
|
if (!strlen(config_dir())) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
snprintf(buf, len, "%s/rc.xml", config_dir());
|
snprintf(buf, len, "%s/rc.xml", config_dir());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_config_file(char *buffer, size_t len, const char *filename)
|
static void
|
||||||
|
find_config_file(char *buffer, size_t len, const char *filename)
|
||||||
{
|
{
|
||||||
if (filename) {
|
if (filename) {
|
||||||
snprintf(buffer, len, "%s", filename);
|
snprintf(buffer, len, "%s", filename);
|
||||||
|
|
@ -287,7 +336,8 @@ static void find_config_file(char *buffer, size_t len, const char *filename)
|
||||||
rcxml_path(buffer, len);
|
rcxml_path(buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcxml_read(const char *filename)
|
void
|
||||||
|
rcxml_read(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *stream;
|
FILE *stream;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
|
|
@ -302,8 +352,9 @@ void rcxml_read(const char *filename)
|
||||||
* the first time. The specified 'filename' is only respected the first
|
* the first time. The specified 'filename' is only respected the first
|
||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
if (rcxml[0] == '\0')
|
if (rcxml[0] == '\0') {
|
||||||
find_config_file(rcxml, sizeof(rcxml), filename);
|
find_config_file(rcxml, sizeof(rcxml), filename);
|
||||||
|
}
|
||||||
if (rcxml[0] == '\0') {
|
if (rcxml[0] == '\0') {
|
||||||
warn("cannot find rc.xml config file");
|
warn("cannot find rc.xml config file");
|
||||||
goto no_config;
|
goto no_config;
|
||||||
|
|
@ -331,14 +382,17 @@ no_config:
|
||||||
post_processing();
|
post_processing();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_safe(const void *p)
|
static void
|
||||||
|
free_safe(const void *p)
|
||||||
{
|
{
|
||||||
if (p)
|
if (p) {
|
||||||
free((void *)p);
|
free((void *)p);
|
||||||
|
}
|
||||||
p = NULL;
|
p = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcxml_finish(void)
|
void
|
||||||
|
rcxml_finish(void)
|
||||||
{
|
{
|
||||||
free_safe(rc.font_name_activewindow);
|
free_safe(rc.font_name_activewindow);
|
||||||
free_safe(rc.theme_name);
|
free_safe(rc.theme_name);
|
||||||
|
|
@ -353,7 +407,8 @@ void rcxml_finish(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcxml_get_nodenames(struct buf *b)
|
void
|
||||||
|
rcxml_get_nodenames(struct buf *b)
|
||||||
{
|
{
|
||||||
write_to_nodename_buffer = true;
|
write_to_nodename_buffer = true;
|
||||||
nodename_buffer = b;
|
nodename_buffer = b;
|
||||||
|
|
|
||||||
61
src/cursor.c
61
src/cursor.c
|
|
@ -1,6 +1,7 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
static void process_cursor_move(struct server *server, uint32_t time)
|
static void
|
||||||
|
process_cursor_move(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
/* Move the grabbed view to the new position. */
|
/* Move the grabbed view to the new position. */
|
||||||
double dx = server->cursor->x - server->grab_x;
|
double dx = server->cursor->x - server->grab_x;
|
||||||
|
|
@ -8,8 +9,9 @@ static void process_cursor_move(struct server *server, uint32_t time)
|
||||||
server->grabbed_view->x = server->grab_box.x + dx;
|
server->grabbed_view->x = server->grab_box.x + dx;
|
||||||
server->grabbed_view->y = server->grab_box.y + dy;
|
server->grabbed_view->y = server->grab_box.y + dy;
|
||||||
|
|
||||||
if (server->grabbed_view->type != LAB_XWAYLAND_VIEW)
|
if (server->grabbed_view->type != LAB_XWAYLAND_VIEW) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct view *view = server->grabbed_view;
|
struct view *view = server->grabbed_view;
|
||||||
wlr_xwayland_surface_configure(view->xwayland_surface, view->x, view->y,
|
wlr_xwayland_surface_configure(view->xwayland_surface, view->x, view->y,
|
||||||
|
|
@ -20,7 +22,8 @@ static void process_cursor_move(struct server *server, uint32_t time)
|
||||||
#define MIN_VIEW_WIDTH (100)
|
#define MIN_VIEW_WIDTH (100)
|
||||||
#define MIN_VIEW_HEIGHT (60)
|
#define MIN_VIEW_HEIGHT (60)
|
||||||
|
|
||||||
static void process_cursor_resize(struct server *server, uint32_t time)
|
static void
|
||||||
|
process_cursor_resize(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* TODO: Wait for the client to prepare a buffer at the new size, then
|
* TODO: Wait for the client to prepare a buffer at the new size, then
|
||||||
|
|
@ -47,8 +50,9 @@ static void process_cursor_resize(struct server *server, uint32_t time)
|
||||||
new_view_geo.width = server->grab_box.width + dx;
|
new_view_geo.width = server->grab_box.width + dx;
|
||||||
}
|
}
|
||||||
if ((new_view_geo.height < MIN_VIEW_HEIGHT) ||
|
if ((new_view_geo.height < MIN_VIEW_HEIGHT) ||
|
||||||
(new_view_geo.width < MIN_VIEW_WIDTH))
|
(new_view_geo.width < MIN_VIEW_WIDTH)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Move */
|
/* Move */
|
||||||
view->x = new_view_geo.x;
|
view->x = new_view_geo.x;
|
||||||
|
|
@ -60,7 +64,8 @@ static void process_cursor_resize(struct server *server, uint32_t time)
|
||||||
view_resize(view, new_view_geo);
|
view_resize(view, new_view_geo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_cursor_motion(struct server *server, uint32_t time)
|
static void
|
||||||
|
process_cursor_motion(struct server *server, uint32_t time)
|
||||||
{
|
{
|
||||||
/* If the mode is non-passthrough, delegate to those functions. */
|
/* If the mode is non-passthrough, delegate to those functions. */
|
||||||
if (server->cursor_mode == LAB_CURSOR_MOVE) {
|
if (server->cursor_mode == LAB_CURSOR_MOVE) {
|
||||||
|
|
@ -77,13 +82,15 @@ static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
struct wlr_seat *seat = server->seat;
|
struct wlr_seat *seat = server->seat;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
int view_area;
|
int view_area;
|
||||||
struct view *view = desktop_view_at(server, server->cursor->x,
|
struct view *view =
|
||||||
server->cursor->y, &surface, &sx,
|
desktop_view_at(server, server->cursor->x, server->cursor->y,
|
||||||
&sy, &view_area);
|
&surface, &sx, &sy, &view_area);
|
||||||
if (!view) {
|
if (!view) {
|
||||||
/* If there's no view under the cursor, set the cursor image to
|
/*
|
||||||
|
* If there's no view under the cursor, set the cursor image to
|
||||||
* a default. This is what makes the cursor image appear when
|
* a default. This is what makes the cursor image appear when
|
||||||
* you move it around the screen, not over any views. */
|
* you move it around the screen, not over any views.
|
||||||
|
*/
|
||||||
wlr_xcursor_manager_set_cursor_image(
|
wlr_xcursor_manager_set_cursor_image(
|
||||||
server->cursor_mgr, XCURSOR_DEFAULT, server->cursor);
|
server->cursor_mgr, XCURSOR_DEFAULT, server->cursor);
|
||||||
}
|
}
|
||||||
|
|
@ -114,8 +121,8 @@ static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (surface) {
|
if (surface) {
|
||||||
bool focus_changed = seat->pointer_state.focused_surface !=
|
bool focus_changed =
|
||||||
surface;
|
seat->pointer_state.focused_surface != surface;
|
||||||
/*
|
/*
|
||||||
* "Enter" the surface if necessary. This lets the client know
|
* "Enter" the surface if necessary. This lets the client know
|
||||||
* that the cursor has entered one of its surfaces.
|
* that the cursor has entered one of its surfaces.
|
||||||
|
|
@ -126,8 +133,10 @@ static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
*/
|
*/
|
||||||
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
|
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
|
||||||
if (!focus_changed) {
|
if (!focus_changed) {
|
||||||
/* The enter event contains coordinates, so we only need
|
/*
|
||||||
* to notify on motion if the focus did not change. */
|
* The enter event contains coordinates, so we only need
|
||||||
|
* to notify on motion if the focus did not change.
|
||||||
|
*/
|
||||||
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
|
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -137,7 +146,8 @@ static void process_cursor_motion(struct server *server, uint32_t time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_motion(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_motion(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is forwarded by the cursor when a pointer emits a
|
* This event is forwarded by the cursor when a pointer emits a
|
||||||
|
|
@ -159,7 +169,8 @@ void cursor_motion(struct wl_listener *listener, void *data)
|
||||||
process_cursor_motion(server, event->time_msec);
|
process_cursor_motion(server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_motion_absolute(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_motion_absolute(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is forwarded by the cursor when a pointer emits an
|
* This event is forwarded by the cursor when a pointer emits an
|
||||||
|
|
@ -177,7 +188,8 @@ void cursor_motion_absolute(struct wl_listener *listener, void *data)
|
||||||
process_cursor_motion(server, event->time_msec);
|
process_cursor_motion(server, event->time_msec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_button(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_button(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is forwarded by the cursor when a pointer emits a button
|
* This event is forwarded by the cursor when a pointer emits a button
|
||||||
|
|
@ -196,9 +208,9 @@ void cursor_button(struct wl_listener *listener, void *data)
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
struct wlr_surface *surface;
|
struct wlr_surface *surface;
|
||||||
int view_area;
|
int view_area;
|
||||||
struct view *view = desktop_view_at(server, server->cursor->x,
|
struct view *view =
|
||||||
server->cursor->y, &surface, &sx,
|
desktop_view_at(server, server->cursor->x, server->cursor->y,
|
||||||
&sy, &view_area);
|
&surface, &sx, &sy, &view_area);
|
||||||
if (event->state == WLR_BUTTON_RELEASED) {
|
if (event->state == WLR_BUTTON_RELEASED) {
|
||||||
/* Exit interactive move/resize mode. */
|
/* Exit interactive move/resize mode. */
|
||||||
server->cursor_mode = LAB_CURSOR_PASSTHROUGH;
|
server->cursor_mode = LAB_CURSOR_PASSTHROUGH;
|
||||||
|
|
@ -235,7 +247,8 @@ void cursor_button(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_axis(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_axis(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is forwarded by the cursor when a pointer emits an axis
|
* This event is forwarded by the cursor when a pointer emits an axis
|
||||||
|
|
@ -250,7 +263,8 @@ void cursor_axis(struct wl_listener *listener, void *data)
|
||||||
event->delta_discrete, event->source);
|
event->delta_discrete, event->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_frame(struct wl_listener *listener, void *data)
|
void
|
||||||
|
cursor_frame(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is forwarded by the cursor when a pointer emits an frame
|
* This event is forwarded by the cursor when a pointer emits an frame
|
||||||
|
|
@ -264,7 +278,8 @@ void cursor_frame(struct wl_listener *listener, void *data)
|
||||||
wlr_seat_pointer_notify_frame(server->seat);
|
wlr_seat_pointer_notify_frame(server->seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cursor_new(struct server *server, struct wlr_input_device *device)
|
void
|
||||||
|
cursor_new(struct server *server, struct wlr_input_device *device)
|
||||||
{
|
{
|
||||||
/* TODO: Configure libinput on device to set tap, acceleration, etc */
|
/* TODO: Configure libinput on device to set tap, acceleration, etc */
|
||||||
wlr_cursor_attach_input_device(server->cursor, device);
|
wlr_cursor_attach_input_device(server->cursor, device);
|
||||||
|
|
|
||||||
41
src/dbg.c
41
src/dbg.c
|
|
@ -1,9 +1,10 @@
|
||||||
#include "labwc.h"
|
|
||||||
#include "config/rcxml.h"
|
|
||||||
#include "config/keybind.h"
|
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
#include "config/keybind.h"
|
||||||
|
#include "config/rcxml.h"
|
||||||
|
#include "labwc.h"
|
||||||
|
|
||||||
static int xwl_nr_parents(struct view *view)
|
static int
|
||||||
|
xwl_nr_parents(struct view *view)
|
||||||
{
|
{
|
||||||
struct wlr_xwayland_surface *s = view->xwayland_surface;
|
struct wlr_xwayland_surface *s = view->xwayland_surface;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
@ -19,7 +20,8 @@ static int xwl_nr_parents(struct view *view)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_one_xdg_view(struct view *view)
|
static void
|
||||||
|
show_one_xdg_view(struct view *view)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "XDG ");
|
fprintf(stderr, "XDG ");
|
||||||
switch (view->xdg_surface->role) {
|
switch (view->xdg_surface->role) {
|
||||||
|
|
@ -39,7 +41,8 @@ static void show_one_xdg_view(struct view *view)
|
||||||
view->h);
|
view->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_one_xwl_view(struct view *view)
|
static void
|
||||||
|
show_one_xwl_view(struct view *view)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "XWL ");
|
fprintf(stderr, "XWL ");
|
||||||
fprintf(stderr, "%d ", xwl_nr_parents(view));
|
fprintf(stderr, "%d ", xwl_nr_parents(view));
|
||||||
|
|
@ -67,34 +70,42 @@ static void show_one_xwl_view(struct view *view)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbg_show_one_view(struct view *view)
|
void
|
||||||
|
dbg_show_one_view(struct view *view)
|
||||||
{
|
{
|
||||||
if (!view->surface)
|
if (!view->surface) {
|
||||||
return;
|
return;
|
||||||
if (!view->mapped && !view->minimized)
|
}
|
||||||
|
if (!view->mapped && !view->minimized) {
|
||||||
return;
|
return;
|
||||||
if (view->type == LAB_XDG_SHELL_VIEW)
|
}
|
||||||
|
if (view->type == LAB_XDG_SHELL_VIEW) {
|
||||||
show_one_xdg_view(view);
|
show_one_xdg_view(view);
|
||||||
else if (view->type == LAB_XWAYLAND_VIEW)
|
} else if (view->type == LAB_XWAYLAND_VIEW) {
|
||||||
show_one_xwl_view(view);
|
show_one_xwl_view(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbg_show_views(struct server *server)
|
void
|
||||||
|
dbg_show_views(struct server *server)
|
||||||
{
|
{
|
||||||
struct view *view;
|
struct view *view;
|
||||||
|
|
||||||
fprintf(stderr, "---\n");
|
fprintf(stderr, "---\n");
|
||||||
fprintf(stderr, "TYPE NR_PNT NR_CLD MAPPED VIEW-POINTER NAME\n");
|
fprintf(stderr, "TYPE NR_PNT NR_CLD MAPPED VIEW-POINTER NAME\n");
|
||||||
wl_list_for_each_reverse (view, &server->views, link)
|
wl_list_for_each_reverse (view, &server->views, link) {
|
||||||
dbg_show_one_view(view);
|
dbg_show_one_view(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbg_show_keybinds()
|
void
|
||||||
|
dbg_show_keybinds()
|
||||||
{
|
{
|
||||||
struct keybind *keybind;
|
struct keybind *keybind;
|
||||||
wl_list_for_each_reverse (keybind, &rc.keybinds, link) {
|
wl_list_for_each_reverse (keybind, &rc.keybinds, link) {
|
||||||
printf("KEY=%s-", keybind->action);
|
printf("KEY=%s-", keybind->action);
|
||||||
for (size_t i = 0; i < keybind->keysyms_len; i++)
|
for (size_t i = 0; i < keybind->keysyms_len; i++) {
|
||||||
printf(" %d\n", keybind->keysyms[i]);
|
printf(" %d\n", keybind->keysyms[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
src/deco.c
17
src/deco.c
|
|
@ -4,13 +4,14 @@
|
||||||
* Copyright Johan Malm 2020
|
* Copyright Johan Malm 2020
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config/rcxml.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "theme/theme.h"
|
#include "theme/theme.h"
|
||||||
#include "config/rcxml.h"
|
|
||||||
|
|
||||||
#define BORDER_WIDTH (2)
|
#define BORDER_WIDTH (2)
|
||||||
|
|
||||||
struct border deco_thickness(struct view *view)
|
struct border
|
||||||
|
deco_thickness(struct view *view)
|
||||||
{
|
{
|
||||||
struct border border = {
|
struct border border = {
|
||||||
.top = rc.title_height + BORDER_WIDTH,
|
.top = rc.title_height + BORDER_WIDTH,
|
||||||
|
|
@ -21,7 +22,8 @@ struct border deco_thickness(struct view *view)
|
||||||
return border;
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_box deco_max_extents(struct view *view)
|
struct wlr_box
|
||||||
|
deco_max_extents(struct view *view)
|
||||||
{
|
{
|
||||||
struct border border = deco_thickness(view);
|
struct border border = deco_thickness(view);
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
|
|
@ -33,7 +35,8 @@ struct wlr_box deco_max_extents(struct view *view)
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
|
struct wlr_box
|
||||||
|
deco_box(struct view *view, enum deco_part deco_part)
|
||||||
{
|
{
|
||||||
struct wlr_box box = { .x = 0, .y = 0, .width = 0, .height = 0 };
|
struct wlr_box box = { .x = 0, .y = 0, .width = 0, .height = 0 };
|
||||||
BUG_ON(!view);
|
BUG_ON(!view);
|
||||||
|
|
@ -92,13 +95,15 @@ struct wlr_box deco_box(struct view *view, enum deco_part deco_part)
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum deco_part deco_at(struct view *view, double lx, double ly)
|
enum deco_part
|
||||||
|
deco_at(struct view *view, double lx, double ly)
|
||||||
{
|
{
|
||||||
enum deco_part deco_part;
|
enum deco_part deco_part;
|
||||||
for (deco_part = 0; deco_part < LAB_DECO_END_MARKER; ++deco_part) {
|
for (deco_part = 0; deco_part < LAB_DECO_END_MARKER; ++deco_part) {
|
||||||
struct wlr_box box = deco_box(view, deco_part);
|
struct wlr_box box = deco_box(view, deco_part);
|
||||||
if (wlr_box_contains_point(&box, lx, ly))
|
if (wlr_box_contains_point(&box, lx, ly)) {
|
||||||
return deco_part;
|
return deco_part;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return LAB_DECO_NONE;
|
return LAB_DECO_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
107
src/desktop.c
107
src/desktop.c
|
|
@ -1,45 +1,56 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
static void move_to_front(struct view *view)
|
static void
|
||||||
|
move_to_front(struct view *view)
|
||||||
{
|
{
|
||||||
wl_list_remove(&view->link);
|
wl_list_remove(&view->link);
|
||||||
wl_list_insert(&view->server->views, &view->link);
|
wl_list_insert(&view->server->views, &view->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_xwayland_surface *top_parent_of(struct view *view)
|
static struct wlr_xwayland_surface *
|
||||||
|
top_parent_of(struct view *view)
|
||||||
{
|
{
|
||||||
struct wlr_xwayland_surface *s = view->xwayland_surface;
|
struct wlr_xwayland_surface *s = view->xwayland_surface;
|
||||||
while (s->parent)
|
while (s->parent) {
|
||||||
s = s->parent;
|
s = s->parent;
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_xwayland_sub_views_to_front(struct view *parent)
|
static void
|
||||||
|
move_xwayland_sub_views_to_front(struct view *parent)
|
||||||
{
|
{
|
||||||
if (!parent || parent->type != LAB_XWAYLAND_VIEW)
|
if (!parent || parent->type != LAB_XWAYLAND_VIEW) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
struct view *view, *next;
|
struct view *view, *next;
|
||||||
wl_list_for_each_reverse_safe(view, next, &parent->server->views, link)
|
wl_list_for_each_reverse_safe(view, next, &parent->server->views, link)
|
||||||
{
|
{
|
||||||
/* need to stop here, otherwise loops keeps going forever */
|
/* need to stop here, otherwise loops keeps going forever */
|
||||||
if (view == parent)
|
if (view == parent) {
|
||||||
break;
|
break;
|
||||||
if (view->type != LAB_XWAYLAND_VIEW)
|
}
|
||||||
|
if (view->type != LAB_XWAYLAND_VIEW) {
|
||||||
continue;
|
continue;
|
||||||
if (!view->mapped && !view->minimized)
|
}
|
||||||
|
if (!view->mapped && !view->minimized) {
|
||||||
continue;
|
continue;
|
||||||
if (top_parent_of(view) != parent->xwayland_surface)
|
}
|
||||||
|
if (top_parent_of(view) != parent->xwayland_surface) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
move_to_front(view);
|
move_to_front(view);
|
||||||
/* TODO: we should probably focus on these too here */
|
/* TODO: we should probably focus on these too here */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Activate/deactivate toplevel surface */
|
/* Activate/deactivate toplevel surface */
|
||||||
static void set_activated(struct wlr_surface *surface, bool activated)
|
static void
|
||||||
|
set_activated(struct wlr_surface *surface, bool activated)
|
||||||
{
|
{
|
||||||
if (!surface)
|
if (!surface) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (wlr_surface_is_xdg_surface(surface)) {
|
if (wlr_surface_is_xdg_surface(surface)) {
|
||||||
struct wlr_xdg_surface *s;
|
struct wlr_xdg_surface *s;
|
||||||
s = wlr_xdg_surface_from_wlr_surface(surface);
|
s = wlr_xdg_surface_from_wlr_surface(surface);
|
||||||
|
|
@ -51,7 +62,8 @@ static void set_activated(struct wlr_surface *surface, bool activated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void focus_view(struct view *view)
|
static void
|
||||||
|
focus_view(struct view *view)
|
||||||
{
|
{
|
||||||
struct server *server = view->server;
|
struct server *server = view->server;
|
||||||
struct wlr_seat *seat = server->seat;
|
struct wlr_seat *seat = server->seat;
|
||||||
|
|
@ -61,8 +73,9 @@ static void focus_view(struct view *view)
|
||||||
/* Don't re-focus an already focused surface. */
|
/* Don't re-focus an already focused surface. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (prev_surface)
|
if (prev_surface) {
|
||||||
set_activated(seat->keyboard_state.focused_surface, false);
|
set_activated(seat->keyboard_state.focused_surface, false);
|
||||||
|
}
|
||||||
|
|
||||||
move_to_front(view);
|
move_to_front(view);
|
||||||
set_activated(view->surface, true);
|
set_activated(view->surface, true);
|
||||||
|
|
@ -74,16 +87,19 @@ static void focus_view(struct view *view)
|
||||||
move_xwayland_sub_views_to_front(view);
|
move_xwayland_sub_views_to_front(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void desktop_focus_view(struct view *view)
|
void
|
||||||
|
desktop_focus_view(struct view *view)
|
||||||
{
|
{
|
||||||
if (!view) {
|
if (!view) {
|
||||||
seat_focus_surface(NULL);
|
seat_focus_surface(NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (view->minimized)
|
if (view->minimized) {
|
||||||
view_unminimize(view); /* this will unmap+focus */
|
/* this will unmap and focus */
|
||||||
else if (view->mapped)
|
view_unminimize(view);
|
||||||
|
} else if (view->mapped) {
|
||||||
focus_view(view);
|
focus_view(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -93,32 +109,38 @@ void desktop_focus_view(struct view *view)
|
||||||
* careful when cycling between views. The only views we should focus are
|
* careful when cycling between views. The only views we should focus are
|
||||||
* those that are already mapped and those that have been minimized.
|
* those that are already mapped and those that have been minimized.
|
||||||
*/
|
*/
|
||||||
static bool isfocusable(struct view *view)
|
static bool
|
||||||
|
isfocusable(struct view *view)
|
||||||
{
|
{
|
||||||
/* filter out those xwayland surfaces that have never been mapped */
|
/* filter out those xwayland surfaces that have never been mapped */
|
||||||
if (!view->surface)
|
if (!view->surface) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return (view->mapped || view->minimized);
|
return (view->mapped || view->minimized);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_focusable_view(struct wl_list *wl_list)
|
static bool
|
||||||
|
has_focusable_view(struct wl_list *wl_list)
|
||||||
{
|
{
|
||||||
struct view *view;
|
struct view *view;
|
||||||
wl_list_for_each (view, wl_list, link) {
|
wl_list_for_each (view, wl_list, link) {
|
||||||
if (isfocusable(view))
|
if (isfocusable(view)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct view *first_view(struct server *server)
|
static struct view *
|
||||||
|
first_view(struct server *server)
|
||||||
{
|
{
|
||||||
struct view *view;
|
struct view *view;
|
||||||
view = wl_container_of(server->views.next, view, link);
|
view = wl_container_of(server->views.next, view, link);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct view *desktop_next_view(struct server *server, struct view *current)
|
struct view *
|
||||||
|
desktop_next_view(struct server *server, struct view *current)
|
||||||
{
|
{
|
||||||
if (!has_focusable_view(&server->views))
|
if (!has_focusable_view(&server->views))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -132,37 +154,43 @@ struct view *desktop_next_view(struct server *server, struct view *current)
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_mapped_view(struct wl_list *wl_list)
|
static bool
|
||||||
|
has_mapped_view(struct wl_list *wl_list)
|
||||||
{
|
{
|
||||||
struct view *view;
|
struct view *view;
|
||||||
wl_list_for_each (view, wl_list, link) {
|
wl_list_for_each (view, wl_list, link) {
|
||||||
if (view->mapped)
|
if (view->mapped) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct view *desktop_next_mapped_view(struct view *current)
|
struct view *
|
||||||
|
desktop_next_mapped_view(struct view *current)
|
||||||
{
|
{
|
||||||
BUG_ON(!current);
|
BUG_ON(!current);
|
||||||
struct server *server = current->server;
|
struct server *server = current->server;
|
||||||
if (!has_mapped_view(&server->views))
|
if (!has_mapped_view(&server->views)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
struct view *view = first_view(server);
|
struct view *view = first_view(server);
|
||||||
do {
|
do {
|
||||||
view = wl_container_of(view->link.next, view, link);
|
view = wl_container_of(view->link.next, view, link);
|
||||||
} while (&view->link == &server->views || !view->mapped);
|
} while (&view->link == &server->views || !view->mapped);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
void desktop_focus_next_mapped_view(struct view *current)
|
void
|
||||||
|
desktop_focus_next_mapped_view(struct view *current)
|
||||||
{
|
{
|
||||||
BUG_ON(!current);
|
BUG_ON(!current);
|
||||||
struct view *view = desktop_next_mapped_view(current);
|
struct view *view = desktop_next_mapped_view(current);
|
||||||
desktop_focus_view(view);
|
desktop_focus_view(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _view_at(struct view *view, double lx, double ly,
|
static bool
|
||||||
struct wlr_surface **surface, double *sx, double *sy)
|
_view_at(struct view *view, double lx, double ly, struct wlr_surface **surface,
|
||||||
|
double *sx, double *sy)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* XDG toplevels may have nested surfaces, such as popup windows for
|
* XDG toplevels may have nested surfaces, such as popup windows for
|
||||||
|
|
@ -197,9 +225,10 @@ static bool _view_at(struct view *view, double lx, double ly,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct view *desktop_view_at(struct server *server, double lx, double ly,
|
struct view *
|
||||||
struct wlr_surface **surface, double *sx,
|
desktop_view_at(struct server *server, double lx, double ly,
|
||||||
double *sy, int *view_area)
|
struct wlr_surface **surface, double *sx, double *sy,
|
||||||
|
int *view_area)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This iterates over all of our surfaces and attempts to find one under
|
* This iterates over all of our surfaces and attempts to find one under
|
||||||
|
|
@ -208,15 +237,19 @@ struct view *desktop_view_at(struct server *server, double lx, double ly,
|
||||||
*/
|
*/
|
||||||
struct view *view;
|
struct view *view;
|
||||||
wl_list_for_each (view, &server->views, link) {
|
wl_list_for_each (view, &server->views, link) {
|
||||||
if (!view->mapped)
|
if (!view->mapped) {
|
||||||
continue;
|
continue;
|
||||||
if (_view_at(view, lx, ly, surface, sx, sy))
|
}
|
||||||
|
if (_view_at(view, lx, ly, surface, sx, sy)) {
|
||||||
return view;
|
return view;
|
||||||
if (!view->server_side_deco)
|
}
|
||||||
|
if (!view->server_side_deco) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
*view_area = deco_at(view, lx, ly);
|
*view_area = deco_at(view, lx, ly);
|
||||||
if (*view_area != LAB_DECO_NONE)
|
if (*view_area != LAB_DECO_NONE) {
|
||||||
return view;
|
return view;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ pango_cairo_show_layout(cairo, layout);
|
||||||
g_object_unref(layout);
|
g_object_unref(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_title_texture(struct wlr_texture **texture, const char *text)
|
void
|
||||||
|
update_title_texture(struct wlr_texture **texture, const char *text)
|
||||||
{
|
{
|
||||||
if (*texture) {
|
if (*texture) {
|
||||||
wlr_texture_destroy(*texture);
|
wlr_texture_destroy(*texture);
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
void interactive_begin(struct view *view, enum cursor_mode mode, uint32_t edges)
|
void
|
||||||
|
interactive_begin(struct view *view, enum cursor_mode mode, uint32_t edges)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This function sets up an interactive move or resize operation, where
|
* This function sets up an interactive move or resize operation, where
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
#include "labwc.h"
|
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
#include "labwc.h"
|
||||||
|
|
||||||
static void keyboard_handle_modifiers(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
keyboard_handle_modifiers(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is raised when a modifier key, such as shift or alt, is
|
* This event is raised when a modifier key, such as shift or alt, is
|
||||||
|
|
@ -21,13 +22,14 @@ static void keyboard_handle_modifiers(struct wl_listener *listener, void *data)
|
||||||
keyboard->server->seat, &keyboard->device->keyboard->modifiers);
|
keyboard->server->seat, &keyboard->device->keyboard->modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool handle_keybinding(struct server *server, uint32_t modifiers,
|
static bool
|
||||||
xkb_keysym_t sym)
|
handle_keybinding(struct server *server, uint32_t modifiers, xkb_keysym_t sym)
|
||||||
{
|
{
|
||||||
struct keybind *keybind;
|
struct keybind *keybind;
|
||||||
wl_list_for_each_reverse (keybind, &rc.keybinds, link) {
|
wl_list_for_each_reverse (keybind, &rc.keybinds, link) {
|
||||||
if (modifiers ^ keybind->modifiers)
|
if (modifiers ^ keybind->modifiers) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
for (size_t i = 0; i < keybind->keysyms_len; i++) {
|
for (size_t i = 0; i < keybind->keysyms_len; i++) {
|
||||||
if (sym == keybind->keysyms[i]) {
|
if (sym == keybind->keysyms[i]) {
|
||||||
action(server, keybind->action,
|
action(server, keybind->action,
|
||||||
|
|
@ -39,7 +41,8 @@ static bool handle_keybinding(struct server *server, uint32_t modifiers,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_handle_key(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
keyboard_handle_key(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/* This event is raised when a key is pressed or released. */
|
/* This event is raised when a key is pressed or released. */
|
||||||
struct keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
struct keyboard *keyboard = wl_container_of(listener, keyboard, key);
|
||||||
|
|
@ -73,9 +76,11 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle compositor key bindings */
|
/* Handle compositor key bindings */
|
||||||
if (event->state == WLR_KEY_PRESSED)
|
if (event->state == WLR_KEY_PRESSED) {
|
||||||
for (int i = 0; i < nsyms; i++)
|
for (int i = 0; i < nsyms; i++) {
|
||||||
handled = handle_keybinding(server, modifiers, syms[i]);
|
handled = handle_keybinding(server, modifiers, syms[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
/* Otherwise, we pass it along to the client. */
|
/* Otherwise, we pass it along to the client. */
|
||||||
|
|
@ -85,7 +90,8 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_new(struct server *server, struct wlr_input_device *device)
|
void
|
||||||
|
keyboard_new(struct server *server, struct wlr_input_device *device)
|
||||||
{
|
{
|
||||||
struct keyboard *keyboard = calloc(1, sizeof(struct keyboard));
|
struct keyboard *keyboard = calloc(1, sizeof(struct keyboard));
|
||||||
keyboard->server = server;
|
keyboard->server = server;
|
||||||
|
|
|
||||||
23
src/main.c
23
src/main.c
|
|
@ -1,25 +1,26 @@
|
||||||
|
#include "common/spawn.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "theme/theme.h"
|
#include "theme/theme.h"
|
||||||
#include "xbm/xbm.h"
|
#include "xbm/xbm.h"
|
||||||
#include "common/spawn.h"
|
|
||||||
|
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <pango/pangocairo.h>
|
#include <pango/pangocairo.h>
|
||||||
|
|
||||||
struct server server = { 0 };
|
|
||||||
struct rcxml rc = { 0 };
|
struct rcxml rc = { 0 };
|
||||||
struct theme theme = { 0 };
|
struct theme theme = { 0 };
|
||||||
|
|
||||||
static const char labwc_usage[] =
|
static const char labwc_usage[] =
|
||||||
"Usage: labwc [-h] [-s <startup-command>] [-c <config-file>]\n";
|
"Usage: labwc [-h] [-s <startup-command>] [-c <config-file>]\n";
|
||||||
|
|
||||||
static void usage(void)
|
static void
|
||||||
|
usage(void)
|
||||||
{
|
{
|
||||||
printf("%s", labwc_usage);
|
printf("%s", labwc_usage);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *startup_cmd = NULL;
|
char *startup_cmd = NULL;
|
||||||
char *config_file = NULL;
|
char *config_file = NULL;
|
||||||
|
|
@ -34,35 +35,35 @@ int main(int argc, char *argv[])
|
||||||
startup_cmd = optarg;
|
startup_cmd = optarg;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
/* fallthrough */
|
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (optind < argc)
|
if (optind < argc) {
|
||||||
usage();
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
wlr_log_init(WLR_ERROR, NULL);
|
wlr_log_init(WLR_ERROR, NULL);
|
||||||
rcxml_read(config_file);
|
rcxml_read(config_file);
|
||||||
|
|
||||||
/* Wayland requires XDG_RUNTIME_DIR to be set */
|
|
||||||
if (!getenv("XDG_RUNTIME_DIR")) {
|
if (!getenv("XDG_RUNTIME_DIR")) {
|
||||||
wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is not set");
|
wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is required to be set");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Catch signals. Maybe SIGHUP for reconfigure */
|
struct server server = { 0 };
|
||||||
|
|
||||||
server_init(&server);
|
server_init(&server);
|
||||||
server_start(&server);
|
server_start(&server);
|
||||||
|
|
||||||
theme_read(rc.theme_name);
|
theme_read(rc.theme_name);
|
||||||
xbm_load(server.renderer);
|
xbm_load(server.renderer);
|
||||||
|
|
||||||
if (startup_cmd)
|
if (startup_cmd) {
|
||||||
spawn_async_no_shell(startup_cmd);
|
spawn_async_no_shell(startup_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
wl_display_run(server.wl_display);
|
wl_display_run(server.wl_display);
|
||||||
|
|
||||||
server_finish(&server);
|
server_finish(&server);
|
||||||
rcxml_finish();
|
rcxml_finish();
|
||||||
pango_cairo_font_map_set_default(NULL);
|
pango_cairo_font_map_set_default(NULL);
|
||||||
|
|
|
||||||
33
src/output.c
33
src/output.c
|
|
@ -7,12 +7,14 @@ struct draw_data {
|
||||||
float *rgba;
|
float *rgba;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void draw_rect(struct draw_data *d, struct wlr_box box)
|
static void
|
||||||
|
draw_rect(struct draw_data *d, struct wlr_box box)
|
||||||
{
|
{
|
||||||
wlr_render_rect(d->renderer, &box, d->rgba, d->transform_matrix);
|
wlr_render_rect(d->renderer, &box, d->rgba, d->transform_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_line(struct draw_data *d, int x1, int y1, int x2, int y2)
|
static void
|
||||||
|
draw_line(struct draw_data *d, int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
.x = x1,
|
.x = x1,
|
||||||
|
|
@ -33,7 +35,8 @@ static void draw_rect_unfilled(struct draw_data *d, struct wlr_box box)
|
||||||
}
|
}
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
static void shrink(struct wlr_box *box, int size)
|
static void
|
||||||
|
shrink(struct wlr_box *box, int size)
|
||||||
{
|
{
|
||||||
box->x += size;
|
box->x += size;
|
||||||
box->y += size;
|
box->y += size;
|
||||||
|
|
@ -41,7 +44,8 @@ static void shrink(struct wlr_box *box, int size)
|
||||||
box->height -= 2 * size;
|
box->height -= 2 * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_cycle_box(struct output *output)
|
static void
|
||||||
|
render_cycle_box(struct output *output)
|
||||||
{
|
{
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
if (!output->server->cycle_view)
|
if (!output->server->cycle_view)
|
||||||
|
|
@ -73,8 +77,9 @@ render_it:
|
||||||
draw_rect_unfilled(&dd, box);
|
draw_rect_unfilled(&dd, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_icon(struct draw_data *d, struct wlr_box box,
|
static void
|
||||||
struct wlr_texture *texture)
|
render_icon(struct draw_data *d, struct wlr_box box,
|
||||||
|
struct wlr_texture *texture)
|
||||||
{
|
{
|
||||||
if (!texture)
|
if (!texture)
|
||||||
return;
|
return;
|
||||||
|
|
@ -101,14 +106,16 @@ static void render_icon(struct draw_data *d, struct wlr_box box,
|
||||||
wlr_render_texture_with_matrix(d->renderer, texture, matrix, 1);
|
wlr_render_texture_with_matrix(d->renderer, texture, matrix, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isbutton(enum deco_part deco_part)
|
static bool
|
||||||
|
isbutton(enum deco_part deco_part)
|
||||||
{
|
{
|
||||||
return deco_part == LAB_DECO_BUTTON_CLOSE ||
|
return deco_part == LAB_DECO_BUTTON_CLOSE ||
|
||||||
deco_part == LAB_DECO_BUTTON_MAXIMIZE ||
|
deco_part == LAB_DECO_BUTTON_MAXIMIZE ||
|
||||||
deco_part == LAB_DECO_BUTTON_ICONIFY;
|
deco_part == LAB_DECO_BUTTON_ICONIFY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_decorations(struct wlr_output *output, struct view *view)
|
static void
|
||||||
|
render_decorations(struct wlr_output *output, struct view *view)
|
||||||
{
|
{
|
||||||
if (!view->server_side_deco)
|
if (!view->server_side_deco)
|
||||||
return;
|
return;
|
||||||
|
|
@ -168,8 +175,8 @@ struct render_data {
|
||||||
struct timespec *when;
|
struct timespec *when;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void render_surface(struct wlr_surface *surface, int sx, int sy,
|
static void
|
||||||
void *data)
|
render_surface(struct wlr_surface *surface, int sx, int sy, void *data)
|
||||||
{
|
{
|
||||||
struct render_data *rdata = data;
|
struct render_data *rdata = data;
|
||||||
|
|
||||||
|
|
@ -224,7 +231,8 @@ static void render_surface(struct wlr_surface *surface, int sx, int sy,
|
||||||
wlr_surface_send_frame_done(surface, rdata->when);
|
wlr_surface_send_frame_done(surface, rdata->when);
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_frame(struct wl_listener *listener, void *data)
|
void
|
||||||
|
output_frame(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/* This function is called every time an output is ready to display a
|
/* This function is called every time an output is ready to display a
|
||||||
* frame, generally at the output's refresh rate (e.g. 60Hz). */
|
* frame, generally at the output's refresh rate (e.g. 60Hz). */
|
||||||
|
|
@ -312,7 +320,8 @@ void output_frame(struct wl_listener *listener, void *data)
|
||||||
wlr_output_commit(output->wlr_output);
|
wlr_output_commit(output->wlr_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_new(struct wl_listener *listener, void *data)
|
void
|
||||||
|
output_new(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/* This event is rasied by the backend when a new output (aka a display
|
/* This event is rasied by the backend when a new output (aka a display
|
||||||
* or monitor) becomes available. */
|
* or monitor) becomes available. */
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
static struct wlr_seat *current_seat;
|
static struct wlr_seat *current_seat;
|
||||||
|
|
||||||
void seat_init(struct wlr_seat *seat)
|
void
|
||||||
|
seat_init(struct wlr_seat *seat)
|
||||||
{
|
{
|
||||||
current_seat = seat;
|
current_seat = seat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void seat_focus_surface(struct wlr_surface *surface)
|
void
|
||||||
|
seat_focus_surface(struct wlr_surface *surface)
|
||||||
{
|
{
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
wlr_seat_keyboard_notify_clear_focus(current_seat);
|
wlr_seat_keyboard_notify_clear_focus(current_seat);
|
||||||
|
|
@ -17,7 +19,8 @@ void seat_focus_surface(struct wlr_surface *surface)
|
||||||
wlr_seat_keyboard_notify_enter(current_seat, surface, NULL, 0, NULL);
|
wlr_seat_keyboard_notify_enter(current_seat, surface, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_surface *seat_focused_surface(void)
|
struct wlr_surface *
|
||||||
|
seat_focused_surface(void)
|
||||||
{
|
{
|
||||||
return current_seat->keyboard_state.focused_surface;
|
return current_seat->keyboard_state.focused_surface;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
src/server.c
46
src/server.c
|
|
@ -1,21 +1,22 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include "config/rcxml.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "theme/theme.h"
|
#include "theme/theme.h"
|
||||||
#include "config/rcxml.h"
|
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
|
||||||
#include <wlr/types/wlr_screencopy_v1.h>
|
|
||||||
#include <wlr/types/wlr_data_control_v1.h>
|
#include <wlr/types/wlr_data_control_v1.h>
|
||||||
|
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||||
#include <wlr/types/wlr_primary_selection_v1.h>
|
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||||
|
#include <wlr/types/wlr_screencopy_v1.h>
|
||||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||||
|
|
||||||
static struct wlr_backend *backend;
|
static struct wlr_backend *backend;
|
||||||
static struct wlr_compositor *compositor;
|
static struct wlr_compositor *compositor;
|
||||||
static struct wl_event_source *sighup_source;
|
static struct wl_event_source *sighup_source;
|
||||||
|
|
||||||
static void server_new_input(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
server_new_input(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This event is raised by the backend when a new input device becomes
|
* This event is raised by the backend when a new input device becomes
|
||||||
|
|
@ -45,7 +46,8 @@ static void server_new_input(struct wl_listener *listener, void *data)
|
||||||
wlr_seat_set_capabilities(server->seat, caps);
|
wlr_seat_set_capabilities(server->seat, caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void seat_request_cursor(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
seat_request_cursor(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct server *server =
|
struct server *server =
|
||||||
wl_container_of(listener, server, request_cursor);
|
wl_container_of(listener, server, request_cursor);
|
||||||
|
|
@ -69,7 +71,8 @@ static void seat_request_cursor(struct wl_listener *listener, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void seat_request_set_selection(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
seat_request_set_selection(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct server *server =
|
struct server *server =
|
||||||
wl_container_of(listener, server, request_set_selection);
|
wl_container_of(listener, server, request_set_selection);
|
||||||
|
|
@ -77,7 +80,8 @@ static void seat_request_set_selection(struct wl_listener *listener, void *data)
|
||||||
wlr_seat_set_selection(server->seat, event->source, event->serial);
|
wlr_seat_set_selection(server->seat, event->source, event->serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reload_config_and_theme(void)
|
static void
|
||||||
|
reload_config_and_theme(void)
|
||||||
{
|
{
|
||||||
rcxml_finish();
|
rcxml_finish();
|
||||||
/* TODO: use rc.config_path */
|
/* TODO: use rc.config_path */
|
||||||
|
|
@ -85,7 +89,8 @@ static void reload_config_and_theme(void)
|
||||||
theme_read(rc.theme_name);
|
theme_read(rc.theme_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_signal(int signal, void *data)
|
static int
|
||||||
|
handle_signal(int signal, void *data)
|
||||||
{
|
{
|
||||||
switch (signal) {
|
switch (signal) {
|
||||||
case SIGHUP:
|
case SIGHUP:
|
||||||
|
|
@ -96,7 +101,8 @@ static int handle_signal(int signal, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_init(struct server *server)
|
void
|
||||||
|
server_init(struct server *server)
|
||||||
{
|
{
|
||||||
server->wl_display = wl_display_create();
|
server->wl_display = wl_display_create();
|
||||||
if (!server->wl_display) {
|
if (!server->wl_display) {
|
||||||
|
|
@ -273,17 +279,20 @@ void server_init(struct server *server)
|
||||||
|
|
||||||
server->cursor_mgr =
|
server->cursor_mgr =
|
||||||
wlr_xcursor_manager_create(XCURSOR_DEFAULT, XCURSOR_SIZE);
|
wlr_xcursor_manager_create(XCURSOR_DEFAULT, XCURSOR_SIZE);
|
||||||
if (!server->cursor_mgr)
|
if (!server->cursor_mgr) {
|
||||||
wlr_log(WLR_ERROR, "cannot create xwayland xcursor manager");
|
wlr_log(WLR_ERROR, "cannot create xwayland xcursor manager");
|
||||||
|
}
|
||||||
|
|
||||||
if (setenv("DISPLAY", server->xwayland->display_name, true) < 0)
|
if (setenv("DISPLAY", server->xwayland->display_name, true) < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland");
|
wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland");
|
||||||
else
|
} else {
|
||||||
wlr_log(WLR_DEBUG, "xwayland is running on display %s",
|
wlr_log(WLR_DEBUG, "xwayland is running on display %s",
|
||||||
server->xwayland->display_name);
|
server->xwayland->display_name);
|
||||||
|
}
|
||||||
|
|
||||||
if (!wlr_xcursor_manager_load(server->cursor_mgr, 1))
|
if (!wlr_xcursor_manager_load(server->cursor_mgr, 1)) {
|
||||||
wlr_log(WLR_ERROR, "cannot load xwayland xcursor theme");
|
wlr_log(WLR_ERROR, "cannot load xwayland xcursor theme");
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_xcursor *xcursor;
|
struct wlr_xcursor *xcursor;
|
||||||
xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr,
|
xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr,
|
||||||
|
|
@ -297,7 +306,8 @@ void server_init(struct server *server)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_start(struct server *server)
|
void
|
||||||
|
server_start(struct server *server)
|
||||||
{
|
{
|
||||||
/* Add a Unix socket to the Wayland display. */
|
/* Add a Unix socket to the Wayland display. */
|
||||||
const char *socket = wl_display_add_socket_auto(server->wl_display);
|
const char *socket = wl_display_add_socket_auto(server->wl_display);
|
||||||
|
|
@ -316,17 +326,19 @@ void server_start(struct server *server)
|
||||||
}
|
}
|
||||||
|
|
||||||
setenv("WAYLAND_DISPLAY", socket, true);
|
setenv("WAYLAND_DISPLAY", socket, true);
|
||||||
if (setenv("WAYLAND_DISPLAY", socket, true) < 0)
|
if (setenv("WAYLAND_DISPLAY", socket, true) < 0) {
|
||||||
wlr_log_errno(WLR_ERROR, "unable to set WAYLAND_DISPLAY");
|
wlr_log_errno(WLR_ERROR, "unable to set WAYLAND_DISPLAY");
|
||||||
else
|
} else {
|
||||||
wlr_log(WLR_DEBUG, "WAYLAND_DISPLAY=%s", socket);
|
wlr_log(WLR_DEBUG, "WAYLAND_DISPLAY=%s", socket);
|
||||||
|
}
|
||||||
|
|
||||||
wl_display_init_shm(server->wl_display);
|
wl_display_init_shm(server->wl_display);
|
||||||
|
|
||||||
wlr_xwayland_set_seat(server->xwayland, server->seat);
|
wlr_xwayland_set_seat(server->xwayland, server->seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_finish(struct server *server)
|
void
|
||||||
|
server_finish(struct server *server)
|
||||||
{
|
{
|
||||||
struct output *o, *o_tmp;
|
struct output *o, *o_tmp;
|
||||||
wl_list_for_each_safe (o, o_tmp, &server->outputs, link) {
|
wl_list_for_each_safe (o, o_tmp, &server->outputs, link) {
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,48 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <glib.h>
|
|
||||||
|
|
||||||
#include "theme/theme.h"
|
|
||||||
#include "common/dir.h"
|
#include "common/dir.h"
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
|
#include "theme/theme.h"
|
||||||
|
|
||||||
static int hex_to_dec(char c)
|
static int
|
||||||
|
hex_to_dec(char c)
|
||||||
{
|
{
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= '0' && c <= '9') {
|
||||||
return c - '0';
|
return c - '0';
|
||||||
if (c >= 'a' && c <= 'f')
|
}
|
||||||
|
if (c >= 'a' && c <= 'f') {
|
||||||
return c - 'a' + 10;
|
return c - 'a' + 10;
|
||||||
if (c >= 'A' && c <= 'F')
|
}
|
||||||
|
if (c >= 'A' && c <= 'F') {
|
||||||
return c - 'A' + 10;
|
return c - 'A' + 10;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_hexstr(const char *hex, float *rgba)
|
void
|
||||||
|
parse_hexstr(const char *hex, float *rgba)
|
||||||
{
|
{
|
||||||
if (!hex || hex[0] != '#' || strlen(hex) < 7)
|
if (!hex || hex[0] != '#' || strlen(hex) < 7) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
rgba[0] = (hex_to_dec(hex[1]) * 16 + hex_to_dec(hex[2])) / 255.0;
|
rgba[0] = (hex_to_dec(hex[1]) * 16 + hex_to_dec(hex[2])) / 255.0;
|
||||||
rgba[1] = (hex_to_dec(hex[3]) * 16 + hex_to_dec(hex[4])) / 255.0;
|
rgba[1] = (hex_to_dec(hex[3]) * 16 + hex_to_dec(hex[4])) / 255.0;
|
||||||
rgba[2] = (hex_to_dec(hex[5]) * 16 + hex_to_dec(hex[6])) / 255.0;
|
rgba[2] = (hex_to_dec(hex[5]) * 16 + hex_to_dec(hex[6])) / 255.0;
|
||||||
if (strlen(hex) > 7)
|
if (strlen(hex) > 7) {
|
||||||
rgba[3] = atoi(hex + 7) / 100.0;
|
rgba[3] = atoi(hex + 7) / 100.0;
|
||||||
else
|
} else {
|
||||||
rgba[3] = 1.0;
|
rgba[3] = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool match(const gchar *pattern, const gchar *string)
|
static bool
|
||||||
|
match(const gchar *pattern, const gchar *string)
|
||||||
{
|
{
|
||||||
return (bool)g_pattern_match_simple(pattern, string);
|
return (bool)g_pattern_match_simple(pattern, string);
|
||||||
}
|
}
|
||||||
|
|
@ -42,60 +50,72 @@ static bool match(const gchar *pattern, const gchar *string)
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
static void entry(const char *key, const char *value)
|
static void entry(const char *key, const char *value)
|
||||||
{
|
{
|
||||||
if (!key || !value)
|
if (!key || !value) {
|
||||||
return;
|
return;
|
||||||
if (match(key, "window.active.title.bg.color"))
|
}
|
||||||
|
if (match(key, "window.active.title.bg.color")) {
|
||||||
parse_hexstr(value, theme.window_active_title_bg_color);
|
parse_hexstr(value, theme.window_active_title_bg_color);
|
||||||
if (match(key, "window.active.handle.bg.color"))
|
} else if (match(key, "window.active.handle.bg.color")) {
|
||||||
parse_hexstr(value, theme.window_active_handle_bg_color);
|
parse_hexstr(value, theme.window_active_handle_bg_color);
|
||||||
if (match(key, "window.inactive.title.bg.color"))
|
} else if (match(key, "window.inactive.title.bg.color")) {
|
||||||
parse_hexstr(value, theme.window_inactive_title_bg_color);
|
parse_hexstr(value, theme.window_inactive_title_bg_color);
|
||||||
if (match(key, "window.active.button.unpressed.image.color"))
|
} else if (match(key, "window.active.button.unpressed.image.color")) {
|
||||||
parse_hexstr(value, theme.window_active_button_unpressed_image_color);
|
parse_hexstr(value, theme.window_active_button_unpressed_image_color);
|
||||||
if (match(key, "window.inactive.button.unpressed.image.color"))
|
} else if (match(key, "window.inactive.button.unpressed.image.color")) {
|
||||||
parse_hexstr(value, theme.window_inactive_button_unpressed_image_color);
|
parse_hexstr(value, theme.window_inactive_button_unpressed_image_color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
static void rtrim(char **s)
|
static void
|
||||||
|
rtrim(char **s)
|
||||||
{
|
{
|
||||||
size_t len = strlen(*s);
|
size_t len = strlen(*s);
|
||||||
if (!len)
|
if (!len) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
char *end = *s + len - 1;
|
char *end = *s + len - 1;
|
||||||
while (end >= *s && isspace(*end))
|
while (end >= *s && isspace(*end)) {
|
||||||
end--;
|
end--;
|
||||||
|
}
|
||||||
*(end + 1) = '\0';
|
*(end + 1) = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *strstrip(char *s)
|
static char *
|
||||||
|
strstrip(char *s)
|
||||||
{
|
{
|
||||||
rtrim(&s);
|
rtrim(&s);
|
||||||
while (isspace(*s))
|
while (isspace(*s)) {
|
||||||
s++;
|
s++;
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_config_line(char *line, char **key, char **value)
|
static void
|
||||||
|
parse_config_line(char *line, char **key, char **value)
|
||||||
{
|
{
|
||||||
char *p = strchr(line, ':');
|
char *p = strchr(line, ':');
|
||||||
if (!p)
|
if (!p) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
*key = strstrip(line);
|
*key = strstrip(line);
|
||||||
*value = strstrip(++p);
|
*value = strstrip(++p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_line(char *line)
|
static void
|
||||||
|
process_line(char *line)
|
||||||
{
|
{
|
||||||
if (line[0] == '\0' || line[0] == '#')
|
if (line[0] == '\0' || line[0] == '#') {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
char *key = NULL, *value = NULL;
|
char *key = NULL, *value = NULL;
|
||||||
parse_config_line(line, &key, &value);
|
parse_config_line(line, &key, &value);
|
||||||
entry(key, value);
|
entry(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void theme_read(const char *theme_name)
|
void
|
||||||
|
theme_read(const char *theme_name)
|
||||||
{
|
{
|
||||||
FILE *stream = NULL;
|
FILE *stream = NULL;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
|
|
@ -115,8 +135,9 @@ void theme_read(const char *theme_name)
|
||||||
info("reading themerc (%s)", themerc);
|
info("reading themerc (%s)", themerc);
|
||||||
while (getline(&line, &len, stream) != -1) {
|
while (getline(&line, &len, stream) != -1) {
|
||||||
char *p = strrchr(line, '\n');
|
char *p = strrchr(line, '\n');
|
||||||
if (p)
|
if (p) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
}
|
||||||
process_line(line);
|
process_line(line);
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
|
|
|
||||||
15
src/view.c
15
src/view.c
|
|
@ -1,6 +1,7 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
void view_resize(struct view *view, struct wlr_box geo)
|
void
|
||||||
|
view_resize(struct view *view, struct wlr_box geo)
|
||||||
{
|
{
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
.x = view->x,
|
.x = view->x,
|
||||||
|
|
@ -11,18 +12,22 @@ void view_resize(struct view *view, struct wlr_box geo)
|
||||||
view->impl->configure(view, box);
|
view->impl->configure(view, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_minimize(struct view *view)
|
void
|
||||||
|
view_minimize(struct view *view)
|
||||||
{
|
{
|
||||||
if (view->minimized == true)
|
if (view->minimized == true) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
view->minimized = true;
|
view->minimized = true;
|
||||||
view->impl->unmap(view);
|
view->impl->unmap(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_unminimize(struct view *view)
|
void
|
||||||
|
view_unminimize(struct view *view)
|
||||||
{
|
{
|
||||||
if (view->minimized == false)
|
if (view->minimized == false) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
view->minimized = false;
|
view->minimized = false;
|
||||||
view->impl->map(view);
|
view->impl->map(view);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,32 +5,36 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "xbm/parse.h"
|
|
||||||
#include "common/bug-on.h"
|
#include "common/bug-on.h"
|
||||||
|
#include "xbm/parse.h"
|
||||||
|
|
||||||
static uint32_t color;
|
static uint32_t color;
|
||||||
|
|
||||||
static uint32_t u32(float *rgba)
|
static uint32_t
|
||||||
|
u32(float *rgba)
|
||||||
{
|
{
|
||||||
uint32_t r[4] = { 0 };
|
uint32_t r[4] = { 0 };
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++) {
|
||||||
r[i] = rgba[i] * 255;
|
r[i] = rgba[i] * 255;
|
||||||
|
}
|
||||||
return ((r[3] & 0xff) << 24) | ((r[0] & 0xff) << 16) |
|
return ((r[3] & 0xff) << 24) | ((r[0] & 0xff) << 16) |
|
||||||
((r[1] & 0xff) << 8) | (r[2] & 0xff);
|
((r[1] & 0xff) << 8) | (r[2] & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_set_color(float *rgba)
|
void
|
||||||
|
parse_set_color(float *rgba)
|
||||||
{
|
{
|
||||||
color = u32(rgba);
|
color = u32(rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_bytes(struct pixmap *pixmap, struct token *tokens)
|
static void
|
||||||
|
process_bytes(struct pixmap *pixmap, struct token *tokens)
|
||||||
{
|
{
|
||||||
pixmap->data = (uint32_t *)calloc(pixmap->width * pixmap->height,
|
pixmap->data = (uint32_t *)calloc(pixmap->width * pixmap->height,
|
||||||
sizeof(uint32_t));
|
sizeof(uint32_t));
|
||||||
|
|
@ -42,33 +46,39 @@ static void process_bytes(struct pixmap *pixmap, struct token *tokens)
|
||||||
++byte;
|
++byte;
|
||||||
++t;
|
++t;
|
||||||
}
|
}
|
||||||
if (!t->type)
|
if (!t->type) {
|
||||||
return;
|
return;
|
||||||
if (t->type != TOKEN_INT)
|
}
|
||||||
|
if (t->type != TOKEN_INT) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
int bit = 1 << (col % 8);
|
int bit = 1 << (col % 8);
|
||||||
if (t->value & bit)
|
if (t->value & bit) {
|
||||||
pixmap->data[row * pixmap->width + col] = color;
|
pixmap->data[row * pixmap->width + col] = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++t;
|
++t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pixmap parse_xbm_tokens(struct token *tokens)
|
struct pixmap
|
||||||
|
parse_xbm_tokens(struct token *tokens)
|
||||||
{
|
{
|
||||||
struct pixmap pixmap = { 0 };
|
struct pixmap pixmap = { 0 };
|
||||||
|
|
||||||
for (struct token *t = tokens; t->type; t++) {
|
for (struct token *t = tokens; t->type; t++) {
|
||||||
if (pixmap.width && pixmap.height) {
|
if (pixmap.width && pixmap.height) {
|
||||||
if (t->type != TOKEN_INT)
|
if (t->type != TOKEN_INT) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
process_bytes(&pixmap, t);
|
process_bytes(&pixmap, t);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (strstr(t->name, "width"))
|
if (strstr(t->name, "width")) {
|
||||||
pixmap.width = atoi((++t)->name);
|
pixmap.width = atoi((++t)->name);
|
||||||
else if (strstr(t->name, "height"))
|
} else if (strstr(t->name, "height")) {
|
||||||
pixmap.height = atoi((++t)->name);
|
pixmap.height = atoi((++t)->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return pixmap;
|
return pixmap;
|
||||||
|
|
@ -79,7 +89,8 @@ out:
|
||||||
* function to cope wit that max size
|
* function to cope wit that max size
|
||||||
*/
|
*/
|
||||||
#define LABWC_BUILTIN_ICON_MAX_SIZE (8)
|
#define LABWC_BUILTIN_ICON_MAX_SIZE (8)
|
||||||
struct pixmap parse_xbm_builtin(const char *button, int size)
|
struct pixmap
|
||||||
|
parse_xbm_builtin(const char *button, int size)
|
||||||
{
|
{
|
||||||
struct pixmap pixmap = { 0 };
|
struct pixmap pixmap = { 0 };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ static char *current_buffer_position;
|
||||||
static struct token *tokens;
|
static struct token *tokens;
|
||||||
static int nr_tokens, alloc_tokens;
|
static int nr_tokens, alloc_tokens;
|
||||||
|
|
||||||
static void add_token(enum token_type token_type)
|
static void
|
||||||
|
add_token(enum token_type token_type)
|
||||||
{
|
{
|
||||||
if (nr_tokens == alloc_tokens) {
|
if (nr_tokens == alloc_tokens) {
|
||||||
alloc_tokens = (alloc_tokens + 16) * 2;
|
alloc_tokens = (alloc_tokens + 16) * 2;
|
||||||
|
|
@ -26,13 +27,15 @@ static void add_token(enum token_type token_type)
|
||||||
token->type = token_type;
|
token->type = token_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_identifier_token()
|
static void
|
||||||
|
get_identifier_token()
|
||||||
{
|
{
|
||||||
struct token *token = tokens + nr_tokens - 1;
|
struct token *token = tokens + nr_tokens - 1;
|
||||||
token->name[token->pos] = current_buffer_position[0];
|
token->name[token->pos] = current_buffer_position[0];
|
||||||
token->pos++;
|
token->pos++;
|
||||||
if (token->pos == MAX_TOKEN_SIZE - 1)
|
if (token->pos == MAX_TOKEN_SIZE - 1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
current_buffer_position++;
|
current_buffer_position++;
|
||||||
switch (current_buffer_position[0]) {
|
switch (current_buffer_position[0]) {
|
||||||
case '\0':
|
case '\0':
|
||||||
|
|
@ -49,13 +52,15 @@ static void get_identifier_token()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_number_token()
|
static void
|
||||||
|
get_number_token()
|
||||||
{
|
{
|
||||||
struct token *token = tokens + nr_tokens - 1;
|
struct token *token = tokens + nr_tokens - 1;
|
||||||
token->name[token->pos] = current_buffer_position[0];
|
token->name[token->pos] = current_buffer_position[0];
|
||||||
token->pos++;
|
token->pos++;
|
||||||
if (token->pos == MAX_TOKEN_SIZE - 1)
|
if (token->pos == MAX_TOKEN_SIZE - 1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
current_buffer_position++;
|
current_buffer_position++;
|
||||||
switch (current_buffer_position[0]) {
|
switch (current_buffer_position[0]) {
|
||||||
case '\0':
|
case '\0':
|
||||||
|
|
@ -71,14 +76,16 @@ static void get_number_token()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_special_char_token()
|
static void
|
||||||
|
get_special_char_token()
|
||||||
{
|
{
|
||||||
struct token *token = tokens + nr_tokens - 1;
|
struct token *token = tokens + nr_tokens - 1;
|
||||||
token->name[0] = current_buffer_position[0];
|
token->name[0] = current_buffer_position[0];
|
||||||
current_buffer_position++;
|
current_buffer_position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct token *tokenize_xbm(char *buffer)
|
struct token *
|
||||||
|
tokenize_xbm(char *buffer)
|
||||||
{
|
{
|
||||||
tokens = NULL;
|
tokens = NULL;
|
||||||
nr_tokens = 0;
|
nr_tokens = 0;
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "theme/theme.h"
|
|
||||||
#include "xbm/xbm.h"
|
|
||||||
#include "xbm/parse.h"
|
|
||||||
#include "config/rcxml.h"
|
|
||||||
#include "common/dir.h"
|
#include "common/dir.h"
|
||||||
#include "common/grab-file.h"
|
#include "common/grab-file.h"
|
||||||
|
#include "config/rcxml.h"
|
||||||
|
#include "theme/theme.h"
|
||||||
|
#include "xbm/parse.h"
|
||||||
|
#include "xbm/xbm.h"
|
||||||
|
|
||||||
/* built-in 6x6 buttons */
|
/* built-in 6x6 buttons */
|
||||||
char close_button_normal[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
|
char close_button_normal[] = { 0x33, 0x3f, 0x1e, 0x1e, 0x3f, 0x33 };
|
||||||
|
|
@ -20,27 +20,30 @@ char iconify_button_normal[] = { 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f };
|
||||||
char max_button_normal[] = { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f };
|
char max_button_normal[] = { 0x3f, 0x3f, 0x21, 0x21, 0x21, 0x3f };
|
||||||
char max_button_toggled[] = { 0x3e, 0x22, 0x2f, 0x29, 0x39, 0x0f };
|
char max_button_toggled[] = { 0x3e, 0x22, 0x2f, 0x29, 0x39, 0x0f };
|
||||||
|
|
||||||
static struct wlr_texture *texture_from_pixmap(struct wlr_renderer *renderer,
|
static struct wlr_texture *
|
||||||
struct pixmap *pixmap)
|
texture_from_pixmap(struct wlr_renderer *renderer, struct pixmap *pixmap)
|
||||||
{
|
{
|
||||||
if (!pixmap)
|
if (!pixmap) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return wlr_texture_from_pixels(renderer, WL_SHM_FORMAT_ARGB8888,
|
return wlr_texture_from_pixels(renderer, WL_SHM_FORMAT_ARGB8888,
|
||||||
pixmap->width * 4, pixmap->width,
|
pixmap->width * 4, pixmap->width,
|
||||||
pixmap->height, pixmap->data);
|
pixmap->height, pixmap->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_texture *texture_from_builtin(struct wlr_renderer *renderer,
|
static struct wlr_texture *
|
||||||
const char *button)
|
texture_from_builtin(struct wlr_renderer *renderer, const char *button)
|
||||||
{
|
{
|
||||||
struct pixmap pixmap = parse_xbm_builtin(button, 6);
|
struct pixmap pixmap = parse_xbm_builtin(button, 6);
|
||||||
struct wlr_texture *texture = texture_from_pixmap(renderer, &pixmap);
|
struct wlr_texture *texture = texture_from_pixmap(renderer, &pixmap);
|
||||||
if (pixmap.data)
|
if (pixmap.data) {
|
||||||
free(pixmap.data);
|
free(pixmap.data);
|
||||||
|
}
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *xbm_path(const char *button)
|
static char *
|
||||||
|
xbm_path(const char *button)
|
||||||
{
|
{
|
||||||
static char buffer[4096] = { 0 };
|
static char buffer[4096] = { 0 };
|
||||||
snprintf(buffer, sizeof(buffer), "%s/%s", theme_dir(rc.theme_name),
|
snprintf(buffer, sizeof(buffer), "%s/%s", theme_dir(rc.theme_name),
|
||||||
|
|
@ -48,38 +51,48 @@ static char *xbm_path(const char *button)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_button(struct wlr_renderer *renderer, const char *filename,
|
static void
|
||||||
struct wlr_texture **texture, char *button)
|
load_button(struct wlr_renderer *renderer, const char *filename,
|
||||||
|
struct wlr_texture **texture, char *button)
|
||||||
{
|
{
|
||||||
/* Read file into memory as it's easier to tokenzie that way */
|
/* Read file into memory as it's easier to tokenzie that way */
|
||||||
char *buffer = grab_file(xbm_path(filename));
|
char *buffer = grab_file(xbm_path(filename));
|
||||||
if (!buffer)
|
if (!buffer) {
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
struct token *tokens = tokenize_xbm(buffer);
|
struct token *tokens = tokenize_xbm(buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
struct pixmap pixmap = parse_xbm_tokens(tokens);
|
struct pixmap pixmap = parse_xbm_tokens(tokens);
|
||||||
*texture = texture_from_pixmap(renderer, &pixmap);
|
*texture = texture_from_pixmap(renderer, &pixmap);
|
||||||
if (tokens)
|
if (tokens) {
|
||||||
free(tokens);
|
free(tokens);
|
||||||
if (pixmap.data)
|
}
|
||||||
|
if (pixmap.data) {
|
||||||
free(pixmap.data);
|
free(pixmap.data);
|
||||||
|
}
|
||||||
out:
|
out:
|
||||||
if (!(*texture))
|
if (!(*texture)) {
|
||||||
*texture = texture_from_builtin(renderer, button);
|
*texture = texture_from_builtin(renderer, button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clang-format off */
|
void
|
||||||
void xbm_load(struct wlr_renderer *r)
|
xbm_load(struct wlr_renderer *r)
|
||||||
{
|
{
|
||||||
parse_set_color(theme.window_active_button_unpressed_image_color);
|
parse_set_color(theme.window_active_button_unpressed_image_color);
|
||||||
load_button(r, "close.xbm", &theme.xbm_close_active_unpressed, close_button_normal);
|
load_button(r, "close.xbm", &theme.xbm_close_active_unpressed,
|
||||||
load_button(r, "max.xbm", &theme.xbm_maximize_active_unpressed, max_button_normal);
|
close_button_normal);
|
||||||
load_button(r, "iconify.xbm", &theme.xbm_iconify_active_unpressed, iconify_button_normal);
|
load_button(r, "max.xbm", &theme.xbm_maximize_active_unpressed,
|
||||||
|
max_button_normal);
|
||||||
|
load_button(r, "iconify.xbm", &theme.xbm_iconify_active_unpressed,
|
||||||
|
iconify_button_normal);
|
||||||
|
|
||||||
parse_set_color(theme.window_inactive_button_unpressed_image_color);
|
parse_set_color(theme.window_inactive_button_unpressed_image_color);
|
||||||
load_button(r, "close.xbm", &theme.xbm_close_inactive_unpressed, close_button_normal);
|
load_button(r, "close.xbm", &theme.xbm_close_inactive_unpressed,
|
||||||
load_button(r, "max.xbm", &theme.xbm_maximize_inactive_unpressed, max_button_normal);
|
close_button_normal);
|
||||||
load_button(r, "iconify.xbm", &theme.xbm_iconify_inactive_unpressed, iconify_button_normal);
|
load_button(r, "max.xbm", &theme.xbm_maximize_inactive_unpressed,
|
||||||
|
max_button_normal);
|
||||||
|
load_button(r, "iconify.xbm", &theme.xbm_iconify_inactive_unpressed,
|
||||||
|
iconify_button_normal);
|
||||||
}
|
}
|
||||||
/* clang-format on */
|
|
||||||
|
|
|
||||||
69
src/xdg.c
69
src/xdg.c
|
|
@ -7,7 +7,8 @@ struct xdg_deco {
|
||||||
struct wl_listener request_mode;
|
struct wl_listener request_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void xdg_deco_destroy(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
xdg_deco_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xdg_deco *xdg_deco =
|
struct xdg_deco *xdg_deco =
|
||||||
wl_container_of(listener, xdg_deco, destroy);
|
wl_container_of(listener, xdg_deco, destroy);
|
||||||
|
|
@ -16,26 +17,30 @@ static void xdg_deco_destroy(struct wl_listener *listener, void *data)
|
||||||
free(xdg_deco);
|
free(xdg_deco);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_deco_request_mode(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
xdg_deco_request_mode(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xdg_deco *xdg_deco;
|
struct xdg_deco *xdg_deco;
|
||||||
xdg_deco = wl_container_of(listener, xdg_deco, request_mode);
|
xdg_deco = wl_container_of(listener, xdg_deco, request_mode);
|
||||||
enum wlr_xdg_toplevel_decoration_v1_mode mode;
|
enum wlr_xdg_toplevel_decoration_v1_mode mode;
|
||||||
if (rc.xdg_shell_server_side_deco)
|
if (rc.xdg_shell_server_side_deco) {
|
||||||
mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE;
|
||||||
else
|
} else {
|
||||||
mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
mode = WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE;
|
||||||
|
}
|
||||||
wlr_xdg_toplevel_decoration_v1_set_mode(xdg_deco->wlr_decoration, mode);
|
wlr_xdg_toplevel_decoration_v1_set_mode(xdg_deco->wlr_decoration, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdg_toplevel_decoration(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xdg_toplevel_decoration(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct server *server =
|
struct server *server =
|
||||||
wl_container_of(listener, server, xdg_toplevel_decoration);
|
wl_container_of(listener, server, xdg_toplevel_decoration);
|
||||||
struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration = data;
|
struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration = data;
|
||||||
struct xdg_deco *xdg_deco = calloc(1, sizeof(struct xdg_deco));
|
struct xdg_deco *xdg_deco = calloc(1, sizeof(struct xdg_deco));
|
||||||
if (!xdg_deco)
|
if (!xdg_deco) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
xdg_deco->wlr_decoration = wlr_decoration;
|
xdg_deco->wlr_decoration = wlr_decoration;
|
||||||
xdg_deco->server = server;
|
xdg_deco->server = server;
|
||||||
xdg_deco->destroy.notify = xdg_deco_destroy;
|
xdg_deco->destroy.notify = xdg_deco_destroy;
|
||||||
|
|
@ -46,23 +51,26 @@ void xdg_toplevel_decoration(struct wl_listener *listener, void *data)
|
||||||
xdg_deco_request_mode(&xdg_deco->request_mode, wlr_decoration);
|
xdg_deco_request_mode(&xdg_deco->request_mode, wlr_decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool has_ssd(struct view *view)
|
static bool
|
||||||
|
has_ssd(struct view *view)
|
||||||
{
|
{
|
||||||
if (!rc.xdg_shell_server_side_deco)
|
if (!rc.xdg_shell_server_side_deco) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some XDG shells refuse to disable CSD in which case their
|
* Some XDG shells refuse to disable CSD in which case their
|
||||||
* geometry.{x,y} seems to be greater. We filter on that on the
|
* geometry.{x,y} seems to be greater. We filter on that on the
|
||||||
* assumption that this will remain true.
|
* assumption that this will remain true.
|
||||||
*/
|
*/
|
||||||
if (view->xdg_surface->geometry.x || view->xdg_surface->geometry.y)
|
if (view->xdg_surface->geometry.x || view->xdg_surface->geometry.y) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_commit(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_commit(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, commit);
|
struct view *view = wl_container_of(listener, view, commit);
|
||||||
BUG_ON(!view->surface);
|
BUG_ON(!view->surface);
|
||||||
|
|
@ -70,26 +78,30 @@ static void handle_commit(struct wl_listener *listener, void *data)
|
||||||
view->h = view->surface->current.height;
|
view->h = view->surface->current.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_map(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_map(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, map);
|
struct view *view = wl_container_of(listener, view, map);
|
||||||
view->impl->map(view);
|
view->impl->map(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_unmap(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_unmap(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, unmap);
|
struct view *view = wl_container_of(listener, view, unmap);
|
||||||
view->impl->unmap(view);
|
view->impl->unmap(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_destroy(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, destroy);
|
struct view *view = wl_container_of(listener, view, destroy);
|
||||||
wl_list_remove(&view->link);
|
wl_list_remove(&view->link);
|
||||||
free(view);
|
free(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_request_move(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_request_move(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/* This event is raised when a client would like to begin an interactive
|
/* This event is raised when a client would like to begin an interactive
|
||||||
* move, typically because the user clicked on their client-side
|
* move, typically because the user clicked on their client-side
|
||||||
|
|
@ -102,7 +114,8 @@ static void handle_request_move(struct wl_listener *listener, void *data)
|
||||||
interactive_begin(view, LAB_CURSOR_MOVE, 0);
|
interactive_begin(view, LAB_CURSOR_MOVE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_request_resize(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_request_resize(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
/* This event is raised when a client would like to begin an interactive
|
/* This event is raised when a client would like to begin an interactive
|
||||||
* resize, typically because the user clicked on their client-side
|
* resize, typically because the user clicked on their client-side
|
||||||
|
|
@ -116,18 +129,21 @@ static void handle_request_resize(struct wl_listener *listener, void *data)
|
||||||
interactive_begin(view, LAB_CURSOR_RESIZE, event->edges);
|
interactive_begin(view, LAB_CURSOR_RESIZE, event->edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
|
static void
|
||||||
|
xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
|
||||||
{
|
{
|
||||||
wlr_xdg_toplevel_set_size(view->xdg_surface, (uint32_t)geo.width,
|
wlr_xdg_toplevel_set_size(view->xdg_surface, (uint32_t)geo.width,
|
||||||
(uint32_t)geo.height);
|
(uint32_t)geo.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_view_close(struct view *view)
|
static void
|
||||||
|
xdg_toplevel_view_close(struct view *view)
|
||||||
{
|
{
|
||||||
wlr_xdg_toplevel_send_close(view->xdg_surface);
|
wlr_xdg_toplevel_send_close(view->xdg_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct border xdg_shell_border(struct view *view)
|
static struct border
|
||||||
|
xdg_shell_border(struct view *view)
|
||||||
{
|
{
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
|
wlr_xdg_surface_get_geometry(view->xdg_surface, &box);
|
||||||
|
|
@ -140,12 +156,14 @@ static struct border xdg_shell_border(struct view *view)
|
||||||
return border;
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool istopmost(struct view *view)
|
static bool
|
||||||
|
istopmost(struct view *view)
|
||||||
{
|
{
|
||||||
return view->xdg_surface->toplevel->parent == NULL;
|
return view->xdg_surface->toplevel->parent == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_view_map(struct view *view)
|
static void
|
||||||
|
xdg_toplevel_view_map(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = true;
|
view->mapped = true;
|
||||||
view->surface = view->xdg_surface->surface;
|
view->surface = view->xdg_surface->surface;
|
||||||
|
|
@ -172,7 +190,8 @@ static void xdg_toplevel_view_map(struct view *view)
|
||||||
desktop_focus_view(view);
|
desktop_focus_view(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_view_unmap(struct view *view)
|
static void
|
||||||
|
xdg_toplevel_view_unmap(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = false;
|
view->mapped = false;
|
||||||
wl_list_remove(&view->commit.link);
|
wl_list_remove(&view->commit.link);
|
||||||
|
|
@ -186,13 +205,15 @@ static const struct view_impl xdg_toplevel_view_impl = {
|
||||||
.unmap = xdg_toplevel_view_unmap,
|
.unmap = xdg_toplevel_view_unmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
void xdg_surface_new(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xdg_surface_new(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct server *server =
|
struct server *server =
|
||||||
wl_container_of(listener, server, new_xdg_surface);
|
wl_container_of(listener, server, new_xdg_surface);
|
||||||
struct wlr_xdg_surface *xdg_surface = data;
|
struct wlr_xdg_surface *xdg_surface = data;
|
||||||
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
struct view *view = calloc(1, sizeof(struct view));
|
struct view *view = calloc(1, sizeof(struct view));
|
||||||
view->server = server;
|
view->server = server;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
static void unmanaged_handle_request_configure(struct wl_listener *listener,
|
static void
|
||||||
void *data)
|
unmanaged_handle_request_configure(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xwayland_unmanaged *unmanaged =
|
struct xwayland_unmanaged *unmanaged =
|
||||||
wl_container_of(listener, unmanaged, request_configure);
|
wl_container_of(listener, unmanaged, request_configure);
|
||||||
|
|
@ -11,7 +11,8 @@ static void unmanaged_handle_request_configure(struct wl_listener *listener,
|
||||||
ev->height);
|
ev->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmanaged_handle_commit(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
unmanaged_handle_commit(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xwayland_unmanaged *unmanaged =
|
struct xwayland_unmanaged *unmanaged =
|
||||||
wl_container_of(listener, unmanaged, commit);
|
wl_container_of(listener, unmanaged, commit);
|
||||||
|
|
@ -20,7 +21,8 @@ static void unmanaged_handle_commit(struct wl_listener *listener, void *data)
|
||||||
unmanaged->ly = xsurface->y;
|
unmanaged->ly = xsurface->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmanaged_handle_map(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
unmanaged_handle_map(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xwayland_unmanaged *unmanaged =
|
struct xwayland_unmanaged *unmanaged =
|
||||||
wl_container_of(listener, unmanaged, map);
|
wl_container_of(listener, unmanaged, map);
|
||||||
|
|
@ -35,11 +37,13 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data)
|
||||||
unmanaged->lx = xsurface->x;
|
unmanaged->lx = xsurface->x;
|
||||||
unmanaged->ly = xsurface->y;
|
unmanaged->ly = xsurface->y;
|
||||||
|
|
||||||
if (wlr_xwayland_or_surface_wants_focus(xsurface))
|
if (wlr_xwayland_or_surface_wants_focus(xsurface)) {
|
||||||
seat_focus_surface(xsurface->surface);
|
seat_focus_surface(xsurface->surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmanaged_handle_unmap(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
unmanaged_handle_unmap(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xwayland_unmanaged *unmanaged =
|
struct xwayland_unmanaged *unmanaged =
|
||||||
wl_container_of(listener, unmanaged, unmap);
|
wl_container_of(listener, unmanaged, unmap);
|
||||||
|
|
@ -52,15 +56,17 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data)
|
||||||
struct wl_list *list = &unmanaged->server->unmanaged_surfaces;
|
struct wl_list *list = &unmanaged->server->unmanaged_surfaces;
|
||||||
wl_list_for_each (u, list, link) {
|
wl_list_for_each (u, list, link) {
|
||||||
struct wlr_xwayland_surface *prev = u->xwayland_surface;
|
struct wlr_xwayland_surface *prev = u->xwayland_surface;
|
||||||
if (!wlr_xwayland_or_surface_wants_focus(prev))
|
if (!wlr_xwayland_or_surface_wants_focus(prev)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
seat_focus_surface(prev->surface);
|
seat_focus_surface(prev->surface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmanaged_handle_destroy(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
unmanaged_handle_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct xwayland_unmanaged *unmanaged =
|
struct xwayland_unmanaged *unmanaged =
|
||||||
wl_container_of(listener, unmanaged, destroy);
|
wl_container_of(listener, unmanaged, destroy);
|
||||||
|
|
@ -70,8 +76,9 @@ static void unmanaged_handle_destroy(struct wl_listener *listener, void *data)
|
||||||
free(unmanaged);
|
free(unmanaged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xwayland_unmanaged_create(struct server *server,
|
void
|
||||||
struct wlr_xwayland_surface *xsurface)
|
xwayland_unmanaged_create(struct server *server,
|
||||||
|
struct wlr_xwayland_surface *xsurface)
|
||||||
{
|
{
|
||||||
struct xwayland_unmanaged *unmanaged;
|
struct xwayland_unmanaged *unmanaged;
|
||||||
unmanaged = calloc(1, sizeof(struct xwayland_unmanaged));
|
unmanaged = calloc(1, sizeof(struct xwayland_unmanaged));
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
|
||||||
static void handle_commit(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_commit(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, commit);
|
struct view *view = wl_container_of(listener, view, commit);
|
||||||
BUG_ON(!view->surface);
|
BUG_ON(!view->surface);
|
||||||
|
|
@ -10,19 +11,22 @@ static void handle_commit(struct wl_listener *listener, void *data)
|
||||||
view->h = view->surface->current.height;
|
view->h = view->surface->current.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_map(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_map(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, map);
|
struct view *view = wl_container_of(listener, view, map);
|
||||||
view->impl->map(view);
|
view->impl->map(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_unmap(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_unmap(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, unmap);
|
struct view *view = wl_container_of(listener, view, unmap);
|
||||||
view->impl->unmap(view);
|
view->impl->unmap(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_destroy(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_destroy(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, destroy);
|
struct view *view = wl_container_of(listener, view, destroy);
|
||||||
wl_list_remove(&view->link);
|
wl_list_remove(&view->link);
|
||||||
|
|
@ -33,7 +37,8 @@ static void handle_destroy(struct wl_listener *listener, void *data)
|
||||||
free(view);
|
free(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_request_configure(struct wl_listener *listener, void *data)
|
static void
|
||||||
|
handle_request_configure(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct view *view = wl_container_of(listener, view, request_configure);
|
struct view *view = wl_container_of(listener, view, request_configure);
|
||||||
struct wlr_xwayland_surface_configure_event *event = data;
|
struct wlr_xwayland_surface_configure_event *event = data;
|
||||||
|
|
@ -41,38 +46,45 @@ static void handle_request_configure(struct wl_listener *listener, void *data)
|
||||||
event->y, event->width, event->height);
|
event->y, event->width, event->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void configure(struct view *view, struct wlr_box geo)
|
static void
|
||||||
|
configure(struct view *view, struct wlr_box geo)
|
||||||
{
|
{
|
||||||
wlr_xwayland_surface_configure(view->xwayland_surface, (int16_t)geo.x,
|
wlr_xwayland_surface_configure(view->xwayland_surface, (int16_t)geo.x,
|
||||||
(int16_t)geo.y, (uint16_t)geo.width,
|
(int16_t)geo.y, (uint16_t)geo.width,
|
||||||
(uint16_t)geo.height);
|
(uint16_t)geo.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _close(struct view *view)
|
static void
|
||||||
|
_close(struct view *view)
|
||||||
{
|
{
|
||||||
wlr_xwayland_surface_close(view->xwayland_surface);
|
wlr_xwayland_surface_close(view->xwayland_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool want_deco(struct view *view)
|
static bool
|
||||||
|
want_deco(struct view *view)
|
||||||
{
|
{
|
||||||
return view->xwayland_surface->decorations ==
|
return view->xwayland_surface->decorations ==
|
||||||
WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
|
WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void top_left_edge_boundary_check(struct view *view)
|
static void
|
||||||
|
top_left_edge_boundary_check(struct view *view)
|
||||||
{
|
{
|
||||||
struct wlr_box deco = deco_max_extents(view);
|
struct wlr_box deco = deco_max_extents(view);
|
||||||
if (deco.x < 0)
|
if (deco.x < 0) {
|
||||||
view->x -= deco.x;
|
view->x -= deco.x;
|
||||||
if (deco.y < 0)
|
}
|
||||||
|
if (deco.y < 0) {
|
||||||
view->y -= deco.y;
|
view->y -= deco.y;
|
||||||
|
}
|
||||||
struct wlr_box box = {
|
struct wlr_box box = {
|
||||||
.x = view->x, .y = view->y, .width = view->w, .height = view->h
|
.x = view->x, .y = view->y, .width = view->w, .height = view->h
|
||||||
};
|
};
|
||||||
view->impl->configure(view, box);
|
view->impl->configure(view, box);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void map(struct view *view)
|
static void
|
||||||
|
map(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = true;
|
view->mapped = true;
|
||||||
view->x = view->xwayland_surface->x;
|
view->x = view->xwayland_surface->x;
|
||||||
|
|
@ -94,7 +106,8 @@ static void map(struct view *view)
|
||||||
desktop_focus_view(view);
|
desktop_focus_view(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unmap(struct view *view)
|
static void
|
||||||
|
unmap(struct view *view)
|
||||||
{
|
{
|
||||||
view->mapped = false;
|
view->mapped = false;
|
||||||
wl_list_remove(&view->commit.link);
|
wl_list_remove(&view->commit.link);
|
||||||
|
|
@ -108,7 +121,8 @@ static const struct view_impl xwl_view_impl = {
|
||||||
.unmap = unmap,
|
.unmap = unmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
void xwayland_surface_new(struct wl_listener *listener, void *data)
|
void
|
||||||
|
xwayland_surface_new(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct server *server =
|
struct server *server =
|
||||||
wl_container_of(listener, server, new_xwayland_surface);
|
wl_container_of(listener, server, new_xwayland_surface);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue