Update .clang-format

Align with wlroots style
This commit is contained in:
Johan Malm 2020-09-28 20:41:41 +01:00
parent 96b5ab1fc1
commit 96e05057a3
32 changed files with 669 additions and 515 deletions

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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,

View file

@ -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");

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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));

View file

@ -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;

View file

@ -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);

View file

@ -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]);
}
} }
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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. */

View file

@ -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;
} }

View file

@ -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) {

View file

@ -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);

View file

@ -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);
} }

View file

@ -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 };

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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));

View file

@ -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);