Compare commits

..

5 commits

Author SHA1 Message Date
Johan Malm
ca082e7172 build: bump version to 0.9.1 2025-08-02 12:54:05 +01:00
Johan Malm
296e175bdb NEWS.md: update notes for 0.9.1 2025-08-02 12:50:19 +01:00
Consolatis
3e3681858e src/xdg.c: prevent interacting with un-initialized xdg toplevels after unmap
Fixes: #2937
Fixes: #2944

Originally-Reported-By: tranzystorekk via IRC
2025-07-29 20:49:19 +01:00
John Lindgren
39f79c0cd9 img: fix apparent double-free in img_svg_render() failure path
img_svg_render() calls g_object_unref() on the RsvgHandle in its
error path, but the handle is owned by the shared lab_img_data
struct and will be double-freed later by lab_img_destroy().

The double-free was introduced when img_svg_load() was split from
img_svg_render(). The g_object_unref() should have been removed from
img_svg_render() but was missed.

Fixes: 16dbdc64e5
("ssd: rework titlebar button rendering")
2025-07-29 20:47:34 +01:00
John Lindgren
f338af1cc9 xwayland: fix swapped width/height in _NET_WM_ICON stride calculation
Probably slipped through since most window icons are square anyway.
2025-07-29 20:46:48 +01:00
222 changed files with 6269 additions and 9591 deletions

View file

@ -12,21 +12,14 @@ UseTab: Always
IndentWidth: 8
ContinuationIndentWidth: 8
AlignAfterOpenBracket: DontAlign
AlignOperands: false
AlwaysBreakAfterDefinitionReturnType: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Linux
IndentCaseLabels: false
PenaltyBreakOpenParenthesis: 100
PenaltyReturnTypeOnItsOwnLine: 500
SpaceBeforeParens: ControlStatementsExceptControlMacros
ForEachMacros: ['for_each_view',
'for_each_view_reverse',
'wl_array_for_each',
'wl_list_for_each',
'wl_list_for_each_reverse',
'wl_list_for_each_reverse_safe',
'wl_list_for_each_safe']
IncludeCategories:
- Regex: '<.*>'
- Regex: '.*'

View file

@ -17,8 +17,6 @@ on:
- 'src/**'
- 'include/**'
- 'protocols/**'
- 'clients/**'
- 't/**'
- 'scripts/**'
- '.github/workflows/**'
@ -84,7 +82,7 @@ jobs:
pacman -Syu --noconfirm
pacman -S --noconfirm git meson clang wlroots0.19 libdrm libinput \
wayland-protocols cairo pango libxml2 xorg-xwayland librsvg \
libdisplay-info gdb ttf-dejavu foot libsfdo cmocka
libdisplay-info gdb ttf-dejavu foot libsfdo
- name: Install Debian Testing dependencies
if: matrix.name == 'Debian'
@ -94,7 +92,7 @@ jobs:
apt-get upgrade -y
apt-get install -y git gcc clang gdb xwayland
apt-get build-dep -y labwc
apt-get build-dep -y libwlroots-0.19-dev
apt-get build-dep -y libwlroots-0.18-dev
- name: Install FreeBSD dependencies
if: matrix.name == 'FreeBSD'
@ -105,8 +103,7 @@ jobs:
sed -i '' 's/quarterly/latest/' /etc/pkg/FreeBSD.conf
pkg set -yn pkg:mesa-dri # hack to skip llvm dependency
pkg install -y git meson gcc pkgconf cairo pango evdev-proto \
hwdata wayland-protocols libdisplay-info libepoll-shim \
wlroots019
hwdata wayland-protocols wlroots019 libdisplay-info
run: echo "setup done"
- name: Install Void Linux dependencies
@ -170,7 +167,6 @@ jobs:
meson setup build-gcc-release -Dxwayland=enabled \
-Dbuildtype=release -Db_ndebug=true --werror
meson configure build-gcc-release -Dwlroots:b_ndebug=false || true
meson configure build-gcc-release -Dlibsfdo:b_ndebug=false || true
meson compile -C build-gcc-release
' | $TARGET
@ -193,7 +189,6 @@ jobs:
meson setup build-clang-release -Dxwayland=enabled \
-Dbuildtype=release -Db_ndebug=true --werror
meson configure build-clang-release -Dwlroots:b_ndebug=false || true
meson configure build-clang-release -Dlibsfdo:b_ndebug=false || true
meson compile -C build-clang-release
' | $TARGET
@ -209,18 +204,6 @@ jobs:
meson compile -C build-gcc-no-feature
' | $TARGET
# Unit tests, run on Arch only
- name: Build with gcc - unit test
if: matrix.name == 'Arch'
run: |
echo '
cd "$GITHUB_WORKSPACE"
export CC=gcc
meson setup build-gcc-unit-test -Dtest=enabled --werror
meson compile -C build-gcc-unit-test
meson test -C build-gcc-unit-test --print-errorlogs
' | $TARGET
# Runtime tests, these run on Arch and Void only (the later due to libmusl being used)
- name: Build with gcc - runtime test
if: matrix.name == 'Arch'

View file

@ -10,11 +10,9 @@
- [4.2 Devault Deviations](#devault-deviations)
- [4.3 Labwc Specifics](#labwc-specifics)
- [4.3.1 API](#api)
- [4.3.2 The Use of GLib](#the-use-of-glib)
- [4.3.3 The Use of GNU Extensions](#the-use-of-gnu-extensions)
- [4.3.2 The Use of glib](#the-use-of-glib)
- [4.3.3 The use of GNU extensions](#the-use-of-gnu-extensions)
- [4.3.4 Naming Conventions](#naming-conventions)
- [4.3.5 Switch Statements with Variable Declarations](#switch-statements-with-variable-declarations)
- [4.3.6 Order of #includes](#order-of-includes)
- [5. Commit Messages](#commit-messages)
- [6. Unit Tests](#unit-tests)
- [7. Submitting Patches](#submitting-patches)
@ -23,14 +21,14 @@
# How to Contribute
1. Report bugs as GitHub issues. We use a template prompting you to provide
1. Report bugs as github issues. We use a template prompting you to provide
some sensible information such as what happened, what you expected to happen
and steps to reproduce. If applicable try with default configuration. If
you are able to, try debugging (guidelines below).
and steps to reproduce. If applicable try with default configuration. If
you are able to, try to do some debugging (guidelines below).
2. Submit patches as GitHub pull requests. If you wish to introduce significant
2. Submit patches as github pull-requests. If you wish to introduces significant
changes or new features, consult the [scope document], discuss on IRC or via
a GitHub issue first.
a github issue first.
# Debugging
@ -244,21 +242,21 @@ We have a very small, modest API and encourage you to use it.
[common/array.h]: https://github.com/labwc/labwc/blob/master/include/common/array.h
[common/macros.h]: https://github.com/labwc/labwc/blob/master/include/common/macros.h
### The Use of GLib
### The Use of glib
We try to keep the use of GLib pretty minimal for the following reasons:
We try to keep the use of glib pretty minimal for the following reasons:
- The use of GLib has been known to make AddressSanitiser diagnose false
- The use of glib has been known to make AddressSanitiser diagnose false
positives and negatives.
- Log messages coming from GLib functions look inconsistent.
- The use of GLib functions, naming-conventions and iterators in a codebase
- Log messages coming from glib functions look inconsistent.
- The use of glib functions, naming-conventions and iterators in a code base
that is predominantly ANSI C creates a clash which makes readability and
maintainability harder.
- Mixing gmalloc()/malloc() and respective free()s can create problems with
memory pools [^1]
Having said that, with our use of cairo and pango we depend on glib-2.0 anyway,
so linking with it and making use of some of its helper functions comes for free,
Having said that, with our use of cairo and pango we depend on glib-2.0 anyway
so linking with it and making use of some of its helper functions comes for free
and can keep the code simpler.
For example, if we were going to carry out extensive string manipulation,
@ -274,7 +272,7 @@ devs:
- `g_pattern_match_simple()`
When using these types of functions it is often desirable to support with some
GLib code, which is okay provided it is kept local and self-contained. See
glib code, which is okay provided it is kept local and self-contained. See
example from `src/theme.c`:
```
@ -289,9 +287,9 @@ match(const gchar *pattern, const gchar *string)
}
```
### The Use of GNU Extensions
### The use of GNU extensions
We avoid [GNU C extensions] because we want to fit into the ecosystem
We avoid [GNU C extensions] because we want to fit into the eco-system
(wayland and wlroots) we live in.
We do use `__typeof__` which strictly speaking is a GNU C extension (`typeof`)
@ -300,18 +298,18 @@ but through the use of `__` is supported by gcc and clang without defining
in the [`wl_container_of()`] macro which is needed in `wl_list*` and it
does provide pretty big benefits in terms of type safety.
We compile with `-std=c11` because that's what 'wlroots' uses, and we do not
We compile with `-std=c11` because that's what 'wlroots' uses and we do not
want to increase the entry-level for OSs without good reason (and currently
we can't think of one).
### Naming Conventions
There are three types of coordinate systems: surface, output, and layout — for
There are three types of coordinate systems: surface, output and layout - for
which the variables (sx, sy), (ox, oy) and (lx, ly) are used respectively in
line with wlroots.
With the introduction of the scene-graph API, some wlroots functions also use
node coordinates (nx, ny), but we prefer (sx, sy) where possible.
node coordinates (nx, ny) but we prefer (sx, sy) where possible.
We do not worry about namespace issues too much and we try to not make the code
a pain to use just to uniquify names. If we were writing a library we would
@ -325,7 +323,7 @@ We use the prefix `handle_` for signal-handler-functions in order to be
consistent with sway and rootston. For example
`view->request_resize.notify = handle_request_resize`
### Switch Statements with Variable Declarations
### Switch statements with variable declarations
Unlike many modern languages, C doesn't create a new scope after `case FOO:`.
Therefore, we wrap codes following `case FOO:` that include variable
@ -351,26 +349,6 @@ case BAZ:
But please also consider refactoring the code into a separate function if it
becomes lengthy.
### Order of #includes
In new files, please order `#include` lines as follows:
- In each `.c` file, first include the matching `.h` file, if there is
one. For example, `#include "common/font.h"` should come first in
`src/common/font.c`. This practice helps to ensure that each header
compiles cleanly on its own, without implicit dependencies on other
headers being included first.
- Then list any "system" headers (those not part of labwc) in alphabetical
order, using angle brackets. This includes 3rd-party library headers
such as `<cairo.h>`, as well as wlroots headers.
- Then list any other labwc headers in alphabetical order, using quotation
marks and relative to the `include/` folder. Subfolders below `include/`,
such as `common/`, should be specified even when including one header
from another in the same folder (for example, `#include "common/buf.h"`
from `include/common/grab-file.h`).
# Commit Messages
The log messages that explain changes are just as important as the changes
@ -388,11 +366,11 @@ This first line should:
- In most cases be prefixed with "area: " where area refers to a filename
or identifier for the general area of the code being modified.
- Not capitalize the first word following the "area: " prefix, unless
it's a name, acronym, or similar.
it's a name, acronym or similar.
- Skip the full stop
And please wrap the commit message at max 74 characters, otherwise `git log`
and similar look very weird. URLs and other references are exempt.
and similar look so weird. URLs and other references are exempt.
# Unit Tests
@ -404,9 +382,9 @@ In the bigger scheme of validating that the compositor meets users' needs, unit
tests do not contribute a great deal. However, they have a role to play in
providing some verification that stand-alone functions behave as expected.
On this project, writing unit-tests is not compulsory, nor do we measure
On this project, writing unit-tests is not compulsory nor do we measure
coverage. The inclusion of the t/ directory does not signify a move towards
test-driven development. We intend to use unit tests sparingly, and only when
test-driven development. We intend to use unit tests sparingly and only when
devs find them useful.
## Usage
@ -432,17 +410,17 @@ and use the web interface. Adding new languages should work, otherwise the
administrators can be contacted. Suggestions for improving existing translations
can be added without account.
### GitHub Pull Request
### Github Pull Request
Translators can add their `MY_LOCALE.po` files to the `po` directory
based on `po/labwc.pot`, and issue a pull request. To do this they can
based on `po/labwc.pot` and issue a pull request. To do this they can
generate their `MY_LOCALE.po` file in a few steps:
1. Edit the `po/LINGUAS` file to add their locale code in English
alphabetical order to the field of locale codes.
2. Copy the `po/labwc.pot` to `po/MY_LOCALE.po`
3. Edit the newly generated `MY_LOCALE.po` file with some of their
contact and locale details in the header of the file. Then, add the
contact and locale details in the header of the file then add the
translation strings under each English string.
[See this tutorial for further guidance](https://www.labri.fr/perso/fleury/posts/programming/a-quick-gettext-tutorial.html)
@ -483,13 +461,13 @@ follow the steps to be taken:
2. Update `NEWS.md` with the release details and run
`git commit -m 'NEWS.md: update notes for X.Y.Z'`
Note: If new dependencies are needed, make this clear.
3. In `meson.build`, update the version, and (if required) the wlroots
3. In `meson.build` update the version and (if required) the wlroots
dependency version. Then run `git commit -m 'build: bump version to X.Y.Z'`
4. Run `git tag -a X.Y.Z`. The first line of the commit message should be
"labwc X.Y.Z" and the body should be the `NEWS.md` additions removing
hash characters (#) from the headings as these will otherwise be
ignored by git.
5. On GitHub, create a 'Release' as some distros use this as a trigger. Set it
5. On github, create a 'Release' as some distros use this as a trigger. Set it
as 'latest release'.
[scope document]: https://github.com/labwc/labwc-scope#readme
@ -503,10 +481,11 @@ follow the steps to be taken:
[GNU C extensions]: https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
[`wl_container_of()`]: https://github.com/wayland-project/wayland/blob/985ab55d59db45ea62795c76dff5949343e86b2f/src/wayland-util.h#L409
[^1]: The reference documentation for GLib notes that:
[^1]: The reference documentation for glib notes that:
"It's important to match g_malloc() with g_free(), plain malloc() with
free(), and (if you're using C++) new with delete and new[] with
delete[]. Otherwise bad things can happen, since these allocators may use
different memory pools (and new/delete call constructors and
destructors)."
See: https://docs.gtk.org/glib/memory.html
See: https://developer.gimp.org/api/2.0/glib/glib-Memory-Allocation.html

400
NEWS.md
View file

@ -9,7 +9,6 @@ The format is based on [Keep a Changelog]
| Date | All Changes | wlroots version | lines-of-code |
|------------|---------------|-----------------|---------------|
| 2025-10-10 | [0.9.2] | 0.19.1 | 28818 |
| 2025-08-02 | [0.9.1] | 0.19.0 | 28605 |
| 2025-07-11 | [0.9.0] | 0.19.0 | 28586 |
| 2025-05-02 | [0.8.4] | 0.18.2 | 27679 |
@ -38,36 +37,6 @@ The format is based on [Keep a Changelog]
| 2021-04-15 | [0.2.0] | 0.13.0 | 5011 |
| 2021-03-05 | [0.1.0] | 0.12.0 | 4627 |
[unreleased]: NEWS.md#unreleased
[0.9.2]: NEWS.md#092---2025-10-10
[0.9.1]: NEWS.md#091---2025-08-02
[0.9.0]: NEWS.md#090---2025-07-11
[0.8.4]: NEWS.md#084---2025-05-02
[0.8.3]: NEWS.md#083---2025-02-21
[0.8.2]: NEWS.md#082---2024-12-13
[0.8.1]: NEWS.md#081---2024-10-25
[0.8.0]: NEWS.md#080---2024-08-16
[0.7.4]: NEWS.md#074---2024-06-19
[0.7.3]: NEWS.md#073---2024-06-12
[0.7.2]: NEWS.md#072---2024-05-10
[0.7.1]: NEWS.md#071---2024-03-01
[0.7.0]: NEWS.md#070---2023-12-22
[0.6.6]: NEWS.md#065---2023-11-25
[0.6.5]: NEWS.md#064---2023-09-23
[0.6.4]: NEWS.md#063---2023-07-14
[0.6.3]: NEWS.md#062---2023-05-08
[0.6.2]: NEWS.md#061---2023-03-20
[0.6.1]: NEWS.md#060---2023-01-29
[0.6.0]: NEWS.md#060---2022-11-17
[0.5.3]: NEWS.md#053---2022-07-15
[0.5.2]: NEWS.md#052---2022-05-17
[0.5.1]: NEWS.md#051---2022-04-08
[0.5.0]: NEWS.md#050---2022-02-18
[0.4.0]: NEWS.md#040---2021-12-31
[0.3.0]: NEWS.md#030---2021-06-28
[0.2.0]: NEWS.md#020---2021-04-15
[0.1.0]: NEWS.md#010---2021-03-05
## Notes on wlroots-0.19
There are some regression warnings worth noting for the switch to wlroots 0.19:
@ -101,176 +70,13 @@ There are some regression warnings worth noting for the switch to wlroots 0.19:
around a bug on the wlroots side which is expected to be fixed in wlroots
`0.19.1` [#2887]
With wlroots compiled with libwayland (>= 1.24.0), there is an invisible margin
preventing pointer focus on some layer-shell surfaces including those created by
Gtk. In simple words, this is because libwayland now rounds floats a bit
differently [#3099]. There is a pending fix [wlroots-5159].
[wlroots-4878]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4878
[wlroots-5098]:https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5098
[wlroots-5159]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5159
[gtk-8792]: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8792
## unreleased
## [unreleased]
[unreleased-commits]
### Added
- With the window-switcher custom field state specifiers 's' and 'S', show 's'
for shaded window @domo141 [#2895]
- Support `xdg-dialog` protocol to enable better handling of modal dialogs @xi
[#3134]
- labnag: add --keyboard-focus option @tokyo4j [#3120]
- Allow window switcher to temporarily unshade windows using config option
`<windowSwitcher unshade="yes|no"/>` @Amodio @Consolatis [#3124]
- For the 'classic' style window-switcher, add the following theme options:
- `osd.window-switcher.style-classic.item.active.border.color`
- `osd.window-switcher.style-classic.item.active.bg.color`
@tokyo4j [#3118]
### Fixed
- Don't remove newlines when parsing config, menu and XBM because doing so can
cause parser error in some unusual situations like the one shown below.
@tokyo4j [#3148]
```
<!--
-
- Some comments
-
-->
```
### Changed
- If XML documents (like rc.xml and menu.xml) have an XML declaration (typically
`<?xml version="1.0"?>`), this XML declaration must be the first thing in the
document. In previous versions, line breaks (`\n`) were allowed before due to
the way the files were parsed, but this is approach caused other issues like
[#3145] and is contrary to XML syntax. [#3148] [#3153]
- With the window-switcher custom field state specifiers 's' and 'S', change the
display order from M|m|F to m|s|M|F; and increase the size from three
characters wide to four. @domo141 [#2895]
- Call labnag with on-demand keyboard interactivity by default @tokyo4j [#3120]
- Temporarily unshade windows when switching windows. Restore old behaviour with
`<windowSwitcher unshade="no"/>` @Amodio @Consolatis [#3124]
- In the classic style window-switcher, the default color of the selected window
item has been changed to inherit the border color but with 15% opacity
@tokyo4j [#3118]
## 0.9.2 - 2025-10-10
[0.9.2-commits]
### Added
- Allow `SnapToEdge` and `ToggleSnapToEdge` to combine two cardinal directions
with the config option `combine="yes|no"`. [#3081] @tokyo4j
- Support `Border` context for mousebinds as an alias for `Top`...`BRCorner` to
make configuration easier. @tokyo4j [#3047]
- Add window-switcher mode with thumbnails. This can be enabled with:
`<windowSwitcher style="thumbnail">`. @tokyo4j [#2981]
- Add `toggle` option to `GoToDesktop` action. This has the effect of going back
to the last desktop if already on the target. @RainerKuemmerle [#3024]
- Add `<theme maximizedDecoration="titlebar|none"/>` to allow hiding titlebar
when window is maximized. @CosmicFusion @tokyo4j [#3015]
- Use client-send-to-menu as 'Workspace' submenu in built-in client-menu
@johanmalm [#2995]
- Allow overwriting submenu icon to increase flexibility and enhance Openbox
compatibility. @tokyo4j [#2998]
- Allow client-{list-combined,send-to}-menu as submenu of static menu @tokyo4j
[#2994]
- Add `labnag` (a dialog client with message and buttons) and associated
`<prompt>` option in 'If' actions. @johanmalm @Consolatis @tokyo4j [#2699]
- Support config option `<core><promptCommand>` @johanmalm [#3097]
- Allow snapping to corner edges during interactive move with associated config
options `<snapping><cornerRange>`. @tokyo4j [#2885]
- Support new values "up-left", "up-right", "down-left" and "down-right" with
`<action name="(Toggle)SnapToEdge" direction="[value]">` and
`<query tiled="[value]">`. @tokyo4j [#2885]
- XML parsing improvements as listed below. @tokyo4j [#2667] [#2967] [#2971]
- Support nested `If` and `ForEach` actions
- Parse CDATA as text all nodes
- Remove ordering constraint of attributes in `<keybind>`, `<mousebind>` and
`<windowRule>`
- `If` actions now works for menus
- For menus, the `name` argument no longer has to be the first argument of
`<action>`; and the `label` argument no longer has to be the first argument
of `<item>`
- Toggle mousebinds with the `ToggleKeybinds` action @tokyo4j [#2942]
- Add support for direction value 'any' with tiled queries. This allows users
to query for any snap directions without using multiple query statements
@lynxy [#2883]
### Fixed
- On detecting broken icon theme, fall back on 'hicolor' @Consolatis [#3126]
- Restore initially-maximized window position after unplug/plug @tokyo4j [#3042]
- Fix large client-side icon not being loaded when the rendered icon size is
larger than icon sizes from the client. @tokyo4j [#3033]
- Improve debug logging for configuring input devices @jlindgren90 [#3028]
- Fix false positives when matching desktop entries @datMaffin [#3004]
- Prevent accidental downcasting of scale in scaled-icon-buffer to avoid blurry
icons on non-integer scales and a cairo assert when using a output scale < 1.
@Consolatis #2984
- Fix xdg-shell windows moving between outputs due to configure timeout
@jlindgren90 [#2976]
- Fix segfault with toplevel `<separator>` in `menu.xml` @tokyo4j [#2970]
- Prevent hi-res mice triggering scroll actions too often @tokyo4j [#2933]
### Changed
- Change default keybind `W-<arrow>` to combine cardinal directions to support
resizing of windows to fill a quarter of an output. This only affects users
who do not use an `rc.xml` (thereby using default keybinds) or use the
`<keyboard><default/>` option. Previous behavior can be restored by setting
`combine="no"` as shown below. [#3081] @tokyo4j
```
<keybind key="W-Left">
<action name="SnapToEdge" direction="left" combine="no" />
</keybind>
<keybind key="W-Right">
<action name="SnapToEdge" direction="right" combine="no" />
</keybind>
<keybind key="W-Up">
<action name="SnapToEdge" direction="up" combine="no" />
</keybind>
<keybind key="W-Down">
<action name="SnapToEdge" direction="down" combine="no" />
</keybind>
```
- `Focus` and `Raise` on window border press because it is probably what most
people expect and it makes the behavior consistent with that of Openbox.
@johanmalm [#3039] [#3049]
- On interactive resize, only un-maximize the axis/axes that are being resized.
@jlindgren90 [#3043]
- Change theme setting `osd.window-switcher.*` to
`osd.window-switcher.style-classic.*`. Backward compatibility is preserved.
@tokyo4j [#2981]
- In client-list menu, add brackets around the titles of any minimised windows
@davidphilipbarr [#3002]
- Respect client-initiated window resize of non-maximized axis, for example
remember the width of vertically-maximized window resizing itself
horizontally. @jlindgren90 [#3020]
- Remember position of window along non-maximized axis during interactive move.
@jlindgren90 [#3020]
- Restore default libinput device values on reconfigure with empty value, rather
than leaving the old configuration. This makes rc.xml more declarative.
@tokyo4j [#3011]
- Change `If` action when used without a focused window to execute the `<else>`
branch (previously it was just ignored). The reason for this is to make things
more consistent with `<prompt>`. It is not anticipated that this will affect
anyone's workflow but is mentioned here for completeness.
- Make `autoEnableOutputs=no` apply only to drm outputs @jlindgren90 [#2972]
- Take into account `<core><gap>` for edge and region overlays @tokyo4j [#2965]
## 0.9.1 - 2025-08-02
[0.9.1-commits]
## [0.9.1]
This is an earlier-than-usual release containinig bug fixes only. It has been
done on a separate branch to avoid the inclusion of refactoring and new
@ -292,9 +98,7 @@ features.
- Fix swapped width/height in XWayland client `_NET_WM_ICON` stride calculation
[#2909] @jlindgren90
## 0.9.0 - 2025-07-11
[0.9.0-commits]
## [0.9.0]
The main focus has been to port labwc to wlroots 0.19 [#2388] and fix associated
issues. Special thanks to @Consolatis @jlindgren90 for this.
@ -415,9 +219,7 @@ window.*.title.bg.colorTo.splitTo:
</libinput>
```
## 0.8.4 - 2025-05-02
[0.8.4-commits]
## [0.8.4]
This release predominantly consists of bug-fixes, code simplification and
usability improvements. Amongst the new features the most noteworthy is the
@ -481,9 +283,7 @@ release.
- Increase default `<snapping><range>` to 10 to make it easier to snap windows
on the edge between two monitors. @johanmalm [#2602] [#2608]
## 0.8.3 - 2025-02-21
[0.8.3-commits]
## [0.8.3]
The eye-catching new features of this release are undoubtedly:
1. Support for the `ext-workspace` protocol with big thanks to @Consolatis
@ -601,9 +401,7 @@ Notes to package maintainers:
and followMouseRequiresMovement="no" in rc.xml, keyboard-focus semantics
have subtly changed when using the window-switcher. [#2455]
## 0.8.2 - 2024-12-13
[0.8.2-commits]
## [0.8.2]
This is a shorter release cycle compared with the usual 10-week one because it
contains a significant number of stability and cleanliness fixes which warrant
@ -742,9 +540,7 @@ menu.border.color: #aaaaaa
Openbox's behavior and (ii) behave as already described in our own
documentation. [#2380]
## 0.8.1 - 2024-10-25
[0.8.1-commits]
## [0.8.1]
The most noteworthy additions in this release are:
@ -892,9 +688,7 @@ window.inactive.button.shade.unpressed.image.color
per-device configuration of scroll factor (e.g. setting different scroll
factors for mice and touchpads). [#2057]
## 0.8.0 - 2024-08-16
[0.8.0-commits]
## [0.8.0]
The main focus in this release has been to port labwc to wlroots 0.18 and to
grind out associated regressions. Nonetheless, it contains a few non-related
@ -975,9 +769,7 @@ have been attributed with a 'Written-by' against each relevant log entry.
- Make windows stay fullscreen when associated output is disconnected. [#2040]
## 0.7.4 - 2024-06-19
[0.7.4-commits]
## [0.7.4]
### Fixed
@ -985,9 +777,7 @@ have been attributed with a 'Written-by' against each relevant log entry.
- Fix magnifier by disabling direct scanout when active. [#1989]
- Fix crash triggered by pipemenu without parent `<menu>` element. [#1988]
## 0.7.3 - 2024-06-12
[0.7.3-commits]
## [0.7.3]
Following a couple of big releases, this one feels like more steady with lots of
focus on bug fixes and stability. In terms of new features the most noteworthy
@ -1076,9 +866,7 @@ joint effort by @spl237 and @Consolatis.
- Action `MoveToCursor` is deprecated in favour of:
`<action name="AutoPlace" policy="cursor"/>`.
## 0.7.2 - 2024-05-10
[0.7.2-commits]
## [0.7.2]
This release shaped up to be the second in a row that is larger than usual in
terms of both fixes and new features. Significant additions include
@ -1346,9 +1134,7 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff
the DRM backend or by explicit request using environment variable
`LABWC_UPDATE_ACTIVATION_ENV`.
## 0.7.1 - 2024-03-01
[0.7.1-commits]
## [0.7.1]
### Added
@ -1519,9 +1305,7 @@ osd.window-switcher.preview.border.color: #ffffff,#00a2ff,#ffffff
full `app_id`. Consult the labwc-config(5) manual page for more details.
[#1309]
## 0.7.0 - 2023-12-22
[0.7.0-commits]
## [0.7.0] - 2023-12-22
The main effort in this release has gone into porting labwc to wlroots 0.17
and tidying up regressions. Nonetheless, it contains a significant number of
@ -1581,9 +1365,7 @@ Should bug fixes be required against `0.6.6` (built with wlroots `0.16`), a
- Use the GTK3 notebook header color as the default active title color
(small change from `#dddad6` to `#e1dedb`). Written-by: @dimkr
## 0.6.6 - 2023-11-25
[0.6.6-commits]
## [0.6.6] - 2023-11-25
We do not normally call out contributions by core devs in the changelog,
but a special thanks goes to @jlindgren90 in this release for lots of work
@ -1697,9 +1479,7 @@ relating to surface focus and keyboard issues, amongst others.
will not appear anymore.
- Always switch to the workspace containing the view being focused.
## 0.6.5 - 2023-09-23
[0.6.5-commits]
## [0.6.5] - 2023-09-23
### Added
@ -1775,9 +1555,7 @@ relating to surface focus and keyboard issues, amongst others.
- Do not expand environment variables in `Exec` action `<command>`
argument (but still resolve tilde).
## 0.6.4 - 2023-07-14
[0.6.4-commits]
## [0.6.4] - 2023-07-14
### Added
@ -1818,9 +1596,7 @@ relating to surface focus and keyboard issues, amongst others.
- Make `ToggleKeybinds` applicable only to the window that has keyboard focus
when the action is executed.
## 0.6.3 - 2023-05-08
[0.6.3-commits]
## [0.6.3] - 2023-05-08
### Added
@ -1892,9 +1668,7 @@ relating to surface focus and keyboard issues, amongst others.
- Default to follow="true" for SendToDesktop action as per Openbox 3.6
specification.
## 0.6.2 - 2023-03-20
[0.6.2-commits]
## [0.6.2] - 2023-03-20
This release contains refactoring and simplification relating to
view-output association and xdg/xwayland configure/map events.
@ -1956,9 +1730,7 @@ Unless otherwise stated all contributions are by the core-devs
</core>
```
## 0.6.1 - 2023-01-29
[0.6.1-commits]
## [0.6.1] - 2023-01-29
As usual, this release contains lots of refactoring and bug fixes with
particular thanks going to @Consolatis, @jlindgren90, @bi4k8, @Flrian and
@ -2021,9 +1793,7 @@ particular thanks going to @Consolatis, @jlindgren90, @bi4k8, @Flrian and
VS Code and Discord lagging over time. [#553] Written-by: @Joshua-Ashton
- Do not switch output on SnapToEdge if view is maximized. Written-by: @Flrian
## 0.6.0 - 2022-11-17
[0.6.0-commits]
## [0.6.0] - 2022-11-17
This release contains significant refactoring to use the wlroots
scene-graph API. This touches many areas of the code, particularly
@ -2190,9 +1960,7 @@ reported, tested and fixed issues. Particular mentions go to @bi4k8,
exited the compositor by mistake trying to get out of alt-tab cycling
or similar.
## 0.5.3 - 2022-07-15
[0.5.3-commits]
## [0.5.3] - 2022-07-15
### Added
@ -2214,9 +1982,7 @@ reported, tested and fixed issues. Particular mentions go to @bi4k8,
- Do not segfault on missing drag icon. Written-by: @Consolatis
- Fix windows erratically sticking to edges during move/resize [#331] [#309]
## 0.5.2 - 2022-05-17
[0.5.2-commits]
## [0.5.2] - 2022-05-17
This is a minor bugfix release mostly to ease packaging.
@ -2224,9 +1990,7 @@ This is a minor bugfix release mostly to ease packaging.
- Properly use system provided wlroots. Written-by: @eli-schwartz
## 0.5.1 - 2022-04-08
[0.5.1-commits]
## [0.5.1] - 2022-04-08
### Added
@ -2253,9 +2017,7 @@ This is a minor bugfix release mostly to ease packaging.
- Fix qt application crash on touchpad scroll [#225]
Written-by: @Consolatis
## 0.5.0 - 2022-02-18
[0.5.0-commits]
## [0.5.0] - 2022-02-18
As usual, this release contains a bunch of fixes and improvements, of
which the most notable feature-type changes are listed below. A big
@ -2292,9 +2054,7 @@ This release contains the following two breaking changes:
updating any local `rc.xml` settings in accordance with
`docs/rc.xml.all`
## 0.4.0 - 2021-12-31
[0.4.0-commits]
## [0.4.0] - 2021-12-31
Compile with wlroots 0.15.0
@ -2369,9 +2129,7 @@ feature-type changes are listed below.
- The config option `<lab><xdg_shell_server_side_deco>` has changed to
`<core><decoration>` (breaking change)
## 0.3.0 - 2021-06-28
[0.3.0-commits]
## [0.3.0] - 2021-06-28
Compile with wlroots 0.14.0
@ -2382,9 +2140,7 @@ Compile with wlroots 0.14.0
- Do not use Clearlooks-3.4 theme by default, just use built-in theme
- Fix bug which triggered Qt application segfault
## 0.2.0 - 2021-04-15
[0.2.0-commits]
## [0.2.0] - 2021-04-15
Compile with wlroots 0.13.0
@ -2397,9 +2153,7 @@ Compile with wlroots 0.13.0
- Add labwc-environment(5)
- Call `wlr_output_enable_adaptive_sync()` if `LABWC_ADAPTIVE_SYNC` set
## 0.1.0 - 2021-03-05
[0.1.0-commits]
## [0.1.0] - 2021-03-05
Compile with wlroots 0.12.0 and wayland-server >=1.16
@ -2418,35 +2172,34 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16
ShowMenu
[Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
[unreleased-commits]: https://github.com/labwc/labwc/compare/0.9.2...HEAD
[0.9.2-commits]: https://github.com/labwc/labwc/compare/0.9.1...0.9.2
[0.9.1-commits]: https://github.com/labwc/labwc/compare/0.9.0...0.9.1
[0.9.0-commits]: https://github.com/labwc/labwc/compare/0.8.4...0.9.0
[0.8.4-commits]: https://github.com/labwc/labwc/compare/0.8.3...0.8.4
[0.8.3-commits]: https://github.com/labwc/labwc/compare/0.8.2...0.8.3
[0.8.2-commits]: https://github.com/labwc/labwc/compare/0.8.1...0.8.2
[0.8.1-commits]: https://github.com/labwc/labwc/compare/0.8.0...0.8.1
[0.8.0-commits]: https://github.com/labwc/labwc/compare/0.7.3...0.8.0
[0.7.4-commits]: https://github.com/labwc/labwc/compare/0.7.3...0.7.4
[0.7.3-commits]: https://github.com/labwc/labwc/compare/0.7.2...0.7.3
[0.7.2-commits]: https://github.com/labwc/labwc/compare/0.7.1...0.7.2
[0.7.1-commits]: https://github.com/labwc/labwc/compare/0.7.0...0.7.1
[0.7.0-commits]: https://github.com/labwc/labwc/compare/0.6.6...0.7.0
[0.6.6-commits]: https://github.com/labwc/labwc/compare/0.6.5...0.6.6
[0.6.5-commits]: https://github.com/labwc/labwc/compare/0.6.4...0.6.5
[0.6.4-commits]: https://github.com/labwc/labwc/compare/0.6.3...0.6.4
[0.6.3-commits]: https://github.com/labwc/labwc/compare/0.6.2...0.6.3
[0.6.2-commits]: https://github.com/labwc/labwc/compare/0.6.1...0.6.2
[0.6.1-commits]: https://github.com/labwc/labwc/compare/0.6.0...0.6.1
[0.6.0-commits]: https://github.com/labwc/labwc/compare/0.5.0...0.6.0
[0.5.3-commits]: https://github.com/labwc/labwc/compare/0.5.2...0.5.3
[0.5.2-commits]: https://github.com/labwc/labwc/compare/0.5.1...0.5.2
[0.5.1-commits]: https://github.com/labwc/labwc/compare/0.5.0...0.5.1
[0.5.0-commits]: https://github.com/labwc/labwc/compare/0.4.0...0.5.0
[0.4.0-commits]: https://github.com/labwc/labwc/compare/0.3.0...0.4.0
[0.3.0-commits]: https://github.com/labwc/labwc/compare/0.2.0...0.3.0
[0.2.0-commits]: https://github.com/labwc/labwc/compare/0.1.0...0.2.0
[0.1.0-commits]: https://github.com/labwc/labwc/compare/081339e...0.1.0
[unreleased]: https://github.com/labwc/labwc/compare/0.9.0...HEAD
[0.9.1]: https://github.com/labwc/labwc/compare/0.9.0...0.9.1
[0.9.0]: https://github.com/labwc/labwc/compare/0.8.4...0.9.0
[0.8.4]: https://github.com/labwc/labwc/compare/0.8.3...0.8.4
[0.8.3]: https://github.com/labwc/labwc/compare/0.8.2...0.8.3
[0.8.2]: https://github.com/labwc/labwc/compare/0.8.1...0.8.2
[0.8.1]: https://github.com/labwc/labwc/compare/0.8.0...0.8.1
[0.8.0]: https://github.com/labwc/labwc/compare/0.7.3...0.8.0
[0.7.4]: https://github.com/labwc/labwc/compare/0.7.3...0.7.4
[0.7.3]: https://github.com/labwc/labwc/compare/0.7.2...0.7.3
[0.7.2]: https://github.com/labwc/labwc/compare/0.7.1...0.7.2
[0.7.1]: https://github.com/labwc/labwc/compare/0.7.0...0.7.1
[0.7.0]: https://github.com/labwc/labwc/compare/0.6.6...0.7.0
[0.6.6]: https://github.com/labwc/labwc/compare/0.6.5...0.6.6
[0.6.5]: https://github.com/labwc/labwc/compare/0.6.4...0.6.5
[0.6.4]: https://github.com/labwc/labwc/compare/0.6.3...0.6.4
[0.6.3]: https://github.com/labwc/labwc/compare/0.6.2...0.6.3
[0.6.2]: https://github.com/labwc/labwc/compare/0.6.1...0.6.2
[0.6.1]: https://github.com/labwc/labwc/compare/0.6.0...0.6.1
[0.6.0]: https://github.com/labwc/labwc/compare/0.5.0...0.6.0
[0.5.3]: https://github.com/labwc/labwc/compare/0.5.2...0.5.3
[0.5.2]: https://github.com/labwc/labwc/compare/0.5.1...0.5.2
[0.5.1]: https://github.com/labwc/labwc/compare/0.5.0...0.5.1
[0.5.0]: https://github.com/labwc/labwc/compare/0.4.0...0.5.0
[0.4.0]: https://github.com/labwc/labwc/compare/0.3.0...0.4.0
[0.3.0]: https://github.com/labwc/labwc/compare/0.2.0...0.3.0
[0.2.0]: https://github.com/labwc/labwc/compare/0.1.0...0.2.0
[0.1.0]: https://github.com/labwc/labwc/compare/081339e...0.1.0
[#162]: https://github.com/labwc/labwc/pull/162
[#163]: https://github.com/labwc/labwc/pull/163
@ -2793,14 +2546,12 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16
[#2652]: https://github.com/labwc/labwc/pull/2652
[#2653]: https://github.com/labwc/labwc/pull/2653
[#2657]: https://github.com/labwc/labwc/pull/2657
[#2667]: https://github.com/labwc/labwc/pull/2667
[#2669]: https://github.com/labwc/labwc/pull/2669
[#2678]: https://github.com/labwc/labwc/pull/2678
[#2686]: https://github.com/labwc/labwc/pull/2686
[#2688]: https://github.com/labwc/labwc/pull/2688
[#2692]: https://github.com/labwc/labwc/pull/2692
[#2693]: https://github.com/labwc/labwc/pull/2693
[#2699]: https://github.com/labwc/labwc/pull/2699
[#2700]: https://github.com/labwc/labwc/pull/2700
[#2710]: https://github.com/labwc/labwc/pull/2710
[#2713]: https://github.com/labwc/labwc/pull/2713
@ -2844,53 +2595,14 @@ Compile with wlroots 0.12.0 and wayland-server >=1.16
[#2873]: https://github.com/labwc/labwc/pull/2873
[#2874]: https://github.com/labwc/labwc/pull/2874
[#2877]: https://github.com/labwc/labwc/pull/2877
[#2883]: https://github.com/labwc/labwc/pull/2883
[#2885]: https://github.com/labwc/labwc/pull/2885
[#2886]: https://github.com/labwc/labwc/pull/2886
[#2887]: https://github.com/labwc/labwc/pull/2887
[#2891]: https://github.com/labwc/labwc/pull/2891
[#2895]: https://github.com/labwc/labwc/pull/2895
[#2909]: https://github.com/labwc/labwc/pull/2909
[#2910]: https://github.com/labwc/labwc/pull/2910
[#2914]: https://github.com/labwc/labwc/pull/2914
[#2933]: https://github.com/labwc/labwc/pull/2933
[#2937]: https://github.com/labwc/labwc/pull/2937
[#2939]: https://github.com/labwc/labwc/pull/2939
[#2942]: https://github.com/labwc/labwc/pull/2942
[#2943]: https://github.com/labwc/labwc/pull/2943
[#2944]: https://github.com/labwc/labwc/pull/2944
[#2948]: https://github.com/labwc/labwc/pull/2948
[#2965]: https://github.com/labwc/labwc/pull/2965
[#2967]: https://github.com/labwc/labwc/pull/2967
[#2970]: https://github.com/labwc/labwc/pull/2970
[#2971]: https://github.com/labwc/labwc/pull/2971
[#2972]: https://github.com/labwc/labwc/pull/2972
[#2976]: https://github.com/labwc/labwc/pull/2976
[#2981]: https://github.com/labwc/labwc/pull/2981
[#2994]: https://github.com/labwc/labwc/pull/2994
[#2995]: https://github.com/labwc/labwc/pull/2995
[#2998]: https://github.com/labwc/labwc/pull/2998
[#3002]: https://github.com/labwc/labwc/pull/3002
[#3004]: https://github.com/labwc/labwc/pull/3004
[#3011]: https://github.com/labwc/labwc/pull/3011
[#3015]: https://github.com/labwc/labwc/pull/3015
[#3020]: https://github.com/labwc/labwc/pull/3020
[#3024]: https://github.com/labwc/labwc/pull/3024
[#3028]: https://github.com/labwc/labwc/pull/3028
[#3033]: https://github.com/labwc/labwc/pull/3033
[#3039]: https://github.com/labwc/labwc/pull/3039
[#3042]: https://github.com/labwc/labwc/pull/3042
[#3043]: https://github.com/labwc/labwc/pull/3043
[#3047]: https://github.com/labwc/labwc/pull/3047
[#3049]: https://github.com/labwc/labwc/pull/3049
[#3081]: https://github.com/labwc/labwc/pull/3081
[#3097]: https://github.com/labwc/labwc/pull/3097
[#3099]: https://github.com/labwc/labwc/pull/3099
[#3118]: https://github.com/labwc/labwc/pull/3118
[#3120]: https://github.com/labwc/labwc/pull/3120
[#3124]: https://github.com/labwc/labwc/pull/3124
[#3126]: https://github.com/labwc/labwc/pull/3126
[#3134]: https://github.com/labwc/labwc/pull/3134
[#3145]: https://github.com/labwc/labwc/pull/3145
[#3148]: https://github.com/labwc/labwc/pull/3148
[#3153]: https://github.com/labwc/labwc/pull/3153

View file

@ -101,8 +101,21 @@ spend our effort.
A lot of emphasis is put on code simplicity when considering features.
The main development effort is focused on producing a solid foundation for a
stacking compositor rather than adding configuration and theming options.
See [scope] for full details on implemented features.
High-level summary of items that Labwc supports:
- [x] Config files (rc.xml, autostart, shutdown, environment, menu.xml)
- [x] Theme files and xbm/png/svg icons
- [x] Basic desktop and client menus
- [x] HiDPI
- [x] wlroots protocols such as `output-management`, `layer-shell` and
`foreign-toplevel`
- [x] Optionally xwayland
### 1.5 Videos
| video link | date | duration
@ -236,7 +249,7 @@ Suggested apps to use with Labwc:
- Screen shooter: [grim]
- Screen recorder: [wf-recorder]
- Background image: [swaybg]
- Panel: [waybar], [lavalauncher], [sfwbar], [xfce4-panel]
- Panel: [waybar], [yambar], [lavalauncher], [sfwbar], [xfce4-panel]
- Launchers: [bemenu], [fuzzel], [wofi]
- Output managers: [wlopm], [kanshi], [wlr-randr]
- Screen locker: [swaylock]
@ -279,6 +292,7 @@ The default window bar menu can be translated on the [weblate platform](https://
[wf-recorder]: https://github.com/ammen99/wf-recorder
[swaybg]: https://github.com/swaywm/swaybg
[waybar]: https://github.com/Alexays/Waybar
[yambar]: https://codeberg.org/dnkl/yambar
[lavalauncher]: https://sr.ht/~leon_plickat/LavaLauncher
[sfwbar]: https://github.com/LBCrion/sfwbar
[xfce4-panel]: https://gitlab.xfce.org/xfce/xfce4-panel

File diff suppressed because it is too large Load diff

View file

@ -1,59 +0,0 @@
wayland_client = dependency('wayland-client')
wayland_cursor = dependency('wayland-cursor')
nag_sources = files(
'labnag.c',
'pool-buffer.c',
)
wl_protocol_dir = wayland_protos.get_variable('pkgdatadir')
protocols = [
wl_protocol_dir / 'stable/tablet/tablet-v2.xml',
wl_protocol_dir / 'stable/xdg-shell/xdg-shell.xml',
wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml',
'../protocols/wlr-layer-shell-unstable-v1.xml',
]
foreach xml : protocols
nag_sources += custom_target(
xml.underscorify() + '_c',
input: xml,
output: '@BASENAME@-protocol.c',
command: [wayland_scanner, 'private-code', '@INPUT@', '@OUTPUT@'],
)
nag_sources += custom_target(
xml.underscorify() + '_client_h',
input: xml,
output: '@BASENAME@-client-protocol.h',
command: [wayland_scanner, 'client-header', '@INPUT@', '@OUTPUT@'],
)
endforeach
if host_machine.system() in ['freebsd', 'openbsd']
# For signalfd()
epoll_dep = dependency('epoll-shim')
else
epoll_dep = []
endif
executable(
'labnag',
nag_sources,
dependencies: [
cairo,
pangocairo,
glib,
wayland_client,
wayland_cursor,
wlroots,
server_protos,
epoll_dep,
xkbcommon,
],
include_directories: [labwc_inc],
install: true,
)
clients = files('lab-sensible-terminal')
install_data(clients, install_dir: get_option('bindir'))

View file

@ -1,141 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copied from https://github.com/swaywm/sway
*
* Copyright (C) 2016-2017 Drew DeVault
*/
#define _POSIX_C_SOURCE 200809L
#include <cairo.h>
#include <errno.h>
#include <fcntl.h>
#include <pango/pangocairo.h>
#include <stdio.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include "pool-buffer.h"
static int anonymous_shm_open(void)
{
int retries = 100;
do {
// try a probably-unique name
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
pid_t pid = getpid();
char name[50];
snprintf(name, sizeof(name), "/labnag-%x-%x",
(unsigned int)pid, (unsigned int)ts.tv_nsec);
// shm_open guarantees that O_CLOEXEC is set
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fd >= 0) {
shm_unlink(name);
return fd;
}
--retries;
} while (retries > 0 && errno == EEXIST);
return -1;
}
static void buffer_release(void *data, struct wl_buffer *wl_buffer)
{
struct pool_buffer *buffer = data;
buffer->busy = false;
}
static const struct wl_buffer_listener buffer_listener = {
.release = buffer_release
};
static struct pool_buffer *create_buffer(struct wl_shm *shm,
struct pool_buffer *buf, int32_t width, int32_t height,
uint32_t format)
{
uint32_t stride = width * 4;
size_t size = stride * height;
int fd = anonymous_shm_open();
if (fd == -1) {
return NULL;
}
if (ftruncate(fd, size) < 0) {
close(fd);
return NULL;
}
void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
buf->buffer = wl_shm_pool_create_buffer(pool, 0,
width, height, stride, format);
wl_shm_pool_destroy(pool);
close(fd);
buf->size = size;
buf->width = width;
buf->height = height;
buf->data = data;
buf->surface = cairo_image_surface_create_for_data(data,
CAIRO_FORMAT_ARGB32, width, height, stride);
buf->cairo = cairo_create(buf->surface);
buf->pango = pango_cairo_create_context(buf->cairo);
wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
return buf;
}
void destroy_buffer(struct pool_buffer *buffer)
{
if (buffer->buffer) {
wl_buffer_destroy(buffer->buffer);
buffer->buffer = NULL;
}
if (buffer->cairo) {
cairo_destroy(buffer->cairo);
buffer->cairo = NULL;
}
if (buffer->surface) {
cairo_surface_destroy(buffer->surface);
buffer->surface = NULL;
}
if (buffer->pango) {
g_object_unref(buffer->pango);
buffer->pango = NULL;
}
if (buffer->data) {
munmap(buffer->data, buffer->size);
buffer->data = NULL;
}
}
struct pool_buffer *get_next_buffer(struct wl_shm *shm,
struct pool_buffer pool[static 2], uint32_t width, uint32_t height)
{
struct pool_buffer *buffer = NULL;
for (size_t i = 0; i < 2; ++i) {
if (pool[i].busy) {
continue;
}
buffer = &pool[i];
}
if (!buffer) {
return NULL;
}
if (buffer->width != width || buffer->height != height) {
destroy_buffer(buffer);
}
if (!buffer->buffer) {
if (!create_buffer(shm, buffer, width, height,
WL_SHM_FORMAT_ARGB8888)) {
return NULL;
}
}
buffer->busy = true;
return buffer;
}

View file

@ -1,30 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copied from https://github.com/swaywm/sway
*
* Copyright (C) 2016-2017 Drew DeVault
*/
#ifndef LAB_POOL_BUFFER_H
#define LAB_POOL_BUFFER_H
#include <cairo.h>
#include <pango/pangocairo.h>
#include <stdbool.h>
#include <stdint.h>
#include <wayland-client.h>
struct pool_buffer {
struct wl_buffer *buffer;
cairo_surface_t *surface;
cairo_t *cairo;
PangoContext *pango;
uint32_t width, height;
void *data;
size_t size;
bool busy;
};
struct pool_buffer *get_next_buffer(struct wl_shm *shm,
struct pool_buffer pool[static 2], uint32_t width, uint32_t height);
void destroy_buffer(struct pool_buffer *buffer);
#endif /* LAB_POOL_BUFFER_H */

View file

@ -1,143 +0,0 @@
labnag(1)
# NAME
labnag - Show dialog with message and buttons
# SYNOPSIS
_labnag_ [options...]
# OPTIONS
*-B, --button* <text> [<action>]
Create a button with the text _text_ that optionally executes _action_
when pressed. Multiple buttons can be defined by providing the flag
multiple times. Buttons will appear in the order they are provided from
left to right.
*-Z, --button-dismiss* <text> [<action>]
Create a button with the text _text_ that optionally executes _action_
when pressed, and dismisses labnag. Multiple buttons can be defined by
providing the flag multiple times. Buttons will appear in the order
they are provided from left to right.
*-d, --debug*
Enable debugging.
*-e, --edge* top|bottom
Set the edge to use.
*-y, --layer* overlay|top|bottom|background
Set the layer to use.
*-k, --keyboard-focus none|exclusive|on-demand*
Set the policy for keyboard focus.
*-f, --font* <font>
Set the font to use.
*-h, --help*
Show help message and quit.
*-l, --detailed-message*
Read a detailed message from stdin. A button to toggle details will be
added. Details are shown in a scrollable multi-line text area.
*-L, --detailed-button* <text>
Set the text for the button that toggles details. This has no effect if
there is not a detailed message. The default is _Toggle details_.
*-m, --message* <msg>
Set the message text.
*-o, --output* <output>
Set the output to use. This should be the name of a _xdg\_output_.
*-t, --timeout*
Set duration to close dialog. Default is 5 seconds.
*-x, --exclusive-zone*
Use exclusive zone. Default is false.
*-v, --version*
Show the version number and quit.
# APPEARANCE OPTIONS
*--background-color* <RRGGBB[AA]>
Set the color of the background.
*--button-border-color* <RRGGBB[AA]>
Set the color of the button border.
*--border-bottom-color* <RRGGBB[AA]>
Set the color of the bottom border.
*--button-background-color* <RRGGBB[AA]>
Set the color for the background for buttons.
*--text-color* <RRGGBB[AA]>
Set the text color.
*--button-text-color* <RRGGBB[AA]>
Set the button text color.
*--border-bottom-size* <size>
Set the thickness of the bottom border.
*--message-padding* <padding>
Set the padding for the message.
*--details-background-color* <RRGGBB[AA]>
Set the color for the background for details.
*--details-border-size* <size>
Set the thickness for the details border.
*--button-border-size* <size>
Set the thickness for the button border.
*--button-gap* <gap>
Set the size of the gap between buttons.
*--button-dismiss-gap* <gap>
Set the size of the gap between the dismiss button and another button.
*--button-margin-right* <margin>
Set the margin from the right of the dismiss button to edge.
*--button-padding* <padding>
Set the padding for the button text.
# EXAMPLE
This is a simple example of a _labnag_ logout GUI.
```
#!/bin/sh
# logout with labnag
labnag \\
-f "Hack Regular 10"\\
-m "Choose your logout option"\\
-Z " Lock " "gtklock -d"\\
-Z " Logout " "labwc -e"\\
-Z "Shutdown " "systemctl poweroff"\\
-Z " Reboot " "systemctl reboot"\\
-Z "Hibernate" "systemctl hibernate"\\
-Z " Suspend " "systemctl suspend"\\
-Z " Cancel "\\
--background-color 00ffff\\
--button-background-color 00ffff\\
--button-border-color 00ccccaa\\
--text-color 000000\\
--button-text-color 000000\\
--button-gap 8\\
--button-margin-right 0\\
--button-padding 5\\
--button-border-size 2\\
-t 60
```

View file

@ -92,18 +92,10 @@ Actions are used in menus and keyboard/mouse bindings.
Move window relative to its current position. Positive value of x moves
it right, negative left. Positive value of y moves it down, negative up.
*<action name="ToggleSnapToEdge" direction="value" combine="value" />*++
*<action name="SnapToEdge" direction="value" combine="value" />*
Resize window to fill half or quarter the output in the given direction.
*direction* [up|down|left|right|up-left|up-right|down-left|down-right|center]
Direction in which to snap the window.
*combine* [yes|no]
Allows to snap a window to an output corner by combining two
directions. For example, snapping a window to *right* and then
to *up* places it in the *up-right* quarter of the output.
Default is no.
*<action name="ToggleSnapToEdge" direction="value" />*++
*<action name="SnapToEdge" direction="value" />*
Resize window to fill half the output in the given direction. Supports
directions "left", "up", "right", "down" and "center".
ToggleSnapToEdge additionally toggles the active window between
tiled to the given direction and its untiled position.
@ -235,10 +227,10 @@ Actions are used in menus and keyboard/mouse bindings.
window.
*<action name="ToggleKeybinds" />*
Stop handling keybinds/mousebinds other than ToggleKeybinds itself.
This can be used to allow A-Tab and similar keybinds/mousebinds to be
delivered to Virtual Machines, VNC clients or nested compositors.
A second call will restore all original keybinds/mousebinds.
Stop handling keybinds other than ToggleKeybinds itself.
This can be used to allow A-Tab and similar keybinds to be delivered
to Virtual Machines, VNC clients or nested compositors.
A second call will restore all original keybinds.
This action will only affect the window that had keyboard focus when
the binding was executed. Thus when switching to another window, all
@ -285,7 +277,7 @@ Actions are used in menus and keyboard/mouse bindings.
Resizes active window size to width and height of the output when the
window size exceeds the output size.
*<action name="GoToDesktop" to="value" wrap="yes" toggle="no" />*
*<action name="GoToDesktop" to="value" wrap="yes" />*
Switch to workspace.
*to* The workspace to switch to. Supported values are "current", "last",
@ -295,9 +287,6 @@ Actions are used in menus and keyboard/mouse bindings.
*wrap* [yes|no] Wrap around from last desktop to first, and vice
versa. Default yes.
*toggle* [yes|no] Toggle to “last” if already on the workspace that
would be the actual destination. Default no.
*<action name="SendToDesktop" to="value" follow="yes" wrap="yes" />*
Send active window to workspace.
@ -433,7 +422,6 @@ Actions that execute other actions. Used in keyboard/mouse bindings.
```
<action name="If">
<query/>
<prompt message=""/>
<then><action/></then>
<else><action/></else>
</action>
@ -486,7 +474,7 @@ Actions that execute other actions. Used in keyboard/mouse bindings.
The "left" , "right", "left-occupied" and
"right-occupied" directions will not wrap.
*tiled* [up|right|down|left|up-left|up-right|down-left|down-right|center|any]
*tiled* [up|right|down|left|center]
Whether the client is tiled (snapped) along the the
indicated screen edge.
@ -505,26 +493,6 @@ Actions that execute other actions. Used in keyboard/mouse bindings.
This argument is optional.
*prompt*
Display a yes/no prompt dialog (labnag by default). If 'yes' is
selected, the *then* branch will be taken; and similarly with
'no' and *else*. This argument is optional. Note that the syntax
is different to that of Openbox where a prompt element is not
tied to If-actions but would just be a child of the downstream
action. The reason for this difference is increased flexibility
and functionality gained by optionally using an *else* branch.
```
<keybind key="W-q">
<action name="If">
<prompt message="Quit?"/>
<then>
<action name="Exit"/>
</then>
</action>
</keybind>
```
*then*
A list of actions to be executed if the window matches any
query. This argument is optional.

View file

@ -178,7 +178,6 @@ this is for compatibility with Openbox.
<reuseOutputMode>no</reuseOutputMode>
<xwaylandPersistence>no</xwaylandPersistence>
<primarySelection>yes</primarySelection>
<promptCommand>[see details below]</promptCommand>
</core>
```
@ -217,29 +216,12 @@ this is for compatibility with Openbox.
*<core><autoEnableOutputs>* [yes|no]
Automatically enable outputs at startup and when new outputs are
connected. This option applies only to drm outputs. Default is yes.
connected. Default is yes.
Caution: Disabling this option will make the labwc session unusable
unless an external tool such as `wlr-randr` or `kanshi` is used to
manage outputs.
The reason for the existance of this option is that after losing signal
from the PC (e.g. by `wlopm -off`), some monitors do an input detection
that makes it appear (from the PC side) to disconnect and reconnect a
few seconds later, causing the monitor to turn back on again (as labwc
auto-enables newly connected outputs by default).
An example usage pattern to avoid the above behavior looks as follows:
- Set *<core><autoEnableOutputs>* to *no*
- Run kanshi (e.g. from autostart) and rely on it to enable new outputs
- Have swayidle kill and restart kanshi when entering powersave as
follows:
```
swayidle -w timeout 600 \\
'pkill kanshi ; wlopm --off \*' resume 'kanshi & wlopm --on \*'
```
*<core><reuseOutputMode>* [yes|no]
Try to re-use the existing output mode (resolution / refresh rate).
This may prevent unnecessary screenblank delays when starting labwc
@ -260,55 +242,6 @@ this is for compatibility with Openbox.
up/down) in Chromium and electron based clients without inadvertantly
pasting the primary clipboard. Default is yes.
*<core><promptCommand>*
Set command to be invoked for an action prompt (*<action><prompt>*)
The following conversion specifiers are supported:
- *%m*: the *<prompt>* message option
- *%n*: "No" (in local language if translation is available)
- *%y*: "Yes" (in local language if translation is available)
- *%b*: osd.bg.color
- *%t*: osd.label.text.color
The default prompt command is:
```
labnag \\
--message '%m' \\
--button-dismiss '%n' \\
--button-dismiss '%y' \\
--background-color '%b' \\
--text-color '%t' \\
--button-border-color '%t' \\
--border-bottom-color '%t' \\
--button-background-color '%b' \\
--button-text-color '%t' \\
--border-bottom-size 1 \\
--button-border-size 3 \\
--keyboard-focus on-demand \\
--layer overlay \\
--timeout 0
```
Example 1: The prompt can be configured to use a different dialog client
```
<core>
<promptCommand>zenity --question --text="%m"</promptCommand>
</core>
```
Example 2: A more complex zenity command could be used:
```
zenity \\
--question \\
--title="" \\
--text="%m" \\
--ok-label="%y" \\
--cancel-label="%n"
```
## PLACEMENT
```
@ -339,7 +272,7 @@ this is for compatibility with Openbox.
## WINDOW SWITCHER
```
<windowSwitcher show="yes" style="classic" preview="yes" outlines="yes" allWorkspaces="no">
<windowSwitcher show="yes" preview="yes" outlines="yes" allWorkspaces="no">
<fields>
<field content="icon" width="5%" />
<field content="desktop_entry_name" width="30%" />
@ -348,14 +281,10 @@ this is for compatibility with Openbox.
</windowSwitcher>
```
*<windowSwitcher show="" style="" preview="" outlines="" allWorkspaces="" unshade="">*
*<windowSwitcher show="" preview="" outlines="" allWorkspaces="">*
*show* [yes|no] Draw the OnScreenDisplay when switching between
windows. Default is yes.
*style* [classic|thumbnail] Configures the style of the OnScreenDisplay.
"classic" displays window information like icons and titles in a vertical list.
"thumbnail" shows window thumbnail, icon and title in grids.
*preview* [yes|no] Preview the contents of the selected window when
switching between windows. Default is yes.
@ -366,11 +295,8 @@ this is for compatibility with Openbox.
they are on. Default no (that is only windows on the current workspace
are shown).
*unshade* [yes|no] Temporarily unshade windows when switching between
them and permanently unshade on the final selection. Default is yes.
*<windowSwitcher><fields><field content="" width="%">*
Define window switcher fields when using *<windowSwitcher style="classic" />*.
Define window switcher fields.
*content* defines what the field shows and can be any of:
@ -402,9 +328,9 @@ this is for compatibility with Openbox.
fields are:
- 'B' - shell type, values [xwayland|xdg-shell]
- 'b' - shell type (short form), values [X|W]
- 'S' - state of window, values [m|s|M|F] (4 spaces allocated)
(minimized, shaded, maximized, fullscreen)
- 's' - state of window (short form), values [m|s|M|F] (1 space)
- 'S' - state of window, values [M|m|F] (3 spaces allocated)
(maximized, minimized, fullscreen)
- 's' - state of window (short form), values [M|m|F] (1 space)
- 'I' - wm-class/app-id
- 'i' - wm-class/app-id trimmed, remove "org." if available
- 'n' - desktop entry/file application name, falls back to
@ -486,13 +412,11 @@ activated with SnapToEdge actions or, optionally, by dragging windows to the
edges of an output. Edge snapping causes a window to occupy half of its output,
extending outward from the snapped edge.
*<snapping><range>*++
*<snapping><cornerRange>*
If an interactive move ends with the cursor within *<range>* pixels of an
output edge, the window is snapped to the edge. If it's also within
*<cornerRange>* pixels of an output corner, the window is snapped to the
corner instead. A *<range>* of 0 disables snapping.
Default is 10 for *<range>* and 50 for *<cornerRange>*.
*<snapping><range>*
If an interactive move ends with the cursor a maximum distance *range*,
(in pixels) from the edge of an output, the move will trigger a
SnapToEdge action for that edge. A *range* of 0 disables snapping via
interactive moves. Default is 10.
*<snapping><overlay><enabled>* [yes|no]
Show an overlay when snapping to a window to an edge. Default is yes.
@ -602,11 +526,6 @@ extending outward from the snapped edge.
Even when disabling server side decorations via ToggleDecorations,
keep a small border (and resize area) around the window. Default is yes.
*<theme><maximizedDecoration>* [titlebar|none]
Specify how server side decorations are shown for maximized windows.
*titlebar* shows titlebar above a maximized window. *none* shows no server
side decorations around a maximized window. Default is titlebar.
*<theme><dropShadows>* [yes|no]
Should drop-shadows be rendered behind windows. Default is no.
@ -779,7 +698,7 @@ extending outward from the snapped edge.
W-Return - lab-sensible-terminal
A-F4 - close window
W-a - toggle maximize
W-<arrow> - resize window to fill half or quarter of the output
W-<arrow> - resize window to fill half the output
A-Space - show window menu
```
@ -816,7 +735,6 @@ extending outward from the snapped edge.
- AllDesktops: A button that, by default, toggles omnipresence of a
window.
- Close: A button that, by default, closses a window.
- Border: The window's border including Top...BRCorner below.
- Top: The top edge of the window's border.
- Bottom: The bottom edge of the window's border.
- Left: The left edge of the window's border.

View file

@ -303,79 +303,32 @@ all are supported.
Text color of on-screen-display. Inherits
*window.active.label.text.color* if not set.
*osd.window-switcher.style-classic*
Theme for window switcher when using <windowSwitcher style="classic" />.
See below for details.
*osd.window-switcher.width*
Width of window switcher in pixels. Default is 600.
Width can also be percent of the width of the monitor.
% is mandatory as last character in this case, max 100%
*osd.window-switcher.style-classic.width*
Width of window switcher in pixels. Width can also be a percentage of the
monitor width by adding '%' as suffix (e.g. 70%). Default is 600.
*osd.window-switcher.style-classic.padding*
*osd.window-switcher.padding*
Padding of window switcher in pixels. This is the space between the
window-switcher border and its items. Default is 4.
*osd.window-switcher.style-classic.item.padding.x*
*osd.window-switcher.item.padding.x*
Horizontal padding of window switcher entries in pixels.
Default is 10.
*osd.window-switcher.style-classic.item.padding.y*
*osd.window-switcher.item.padding.y*
Vertical padding of window switcher entries in pixels.
Default is 1.
*osd.window-switcher.style-classic.item.active.border.width*
*osd.window-switcher.item.active.border.width*
Border width of the selection box in the window switcher in pixels.
Default is 2.
*osd.window-switcher.style-classic.item.active.border.color*
Border color around the selected window switcher item.
Default is *osd.label.text.color* with 50% opacity.
*osd.window-switcher.style-classic.item.active.bg.color*
Background color of the selected window switcher item.
Default is *osd.label.text.color* with 15% opacity.
*osd.window-switcher.style-classic.item.icon.size*
*osd.window-switcher.item.icon.size*
Size of the icon in window switcher, in pixels.
If not set, the font size derived from <theme><font place="OnScreenDisplay">
is used.
*osd.window-switcher.style-thumbnail*
Theme for window switcher when using <windowSwitcher style="thumbnail" />.
See below for details.
*osd.window-switcher.style-thumbnail.width.max*
Maximum width of window switcher in pixels. Width can also be a percentage of
the monitor width by adding '%' as suffix (e.g. 70%). Default is 80%.
*osd.window-switcher.style-thumbnail.padding*
Padding of window switcher in pixels. This is the space between the
window-switcher border and its items. Default is 4.
*osd.window-switcher.style-thumbnail.item.width*
Width of window switcher items in pixels. Default is 300.
*osd.window-switcher.style-thumbnail.item.height*
Height of window switcher items in pixels. Default is 250.
*osd.window-switcher.style-thumbnail.item.padding*
Padding of window switcher items in pixels. This is the space between the
border around selected items and window thumbnail. Default is 2.
*osd.window-switcher.style-thumbnail.item.active.border.width*
Border width of selected window switcher items in pixels. Default is 2.
*osd.window-switcher.style-thumbnail.item.active.border.color*
Color of border around selected window switcher items.
Default is *osd.label.text.color* with 50% opacity.
*osd.window-switcher.style-thumbnail.item.active.bg.color*
Color of selected window switcher items.
Default is *osd.label.text.color* with 15% opacity.
*osd.window-switcher.style-thumbnail.item.icon.size*
Size of window icons in window switcher items in pixels. Default is 60.
*osd.window-switcher.preview.border.width*
Border width of the outlines shown as the preview of the window selected
by window switcher. Inherits *osd.border.width* if not set.

View file

@ -134,7 +134,8 @@ example: *LABWC_DEBUG_FOO=1 labwc*.
Increase logging of paths for config files (for example rc.xml,
autostart, environment and menu.xml) as well as titlebar buttons.
*LABWC_DEBUG_CONFIG_NODENAMES*
*LABWC_DEBUG_CONFIG_NODENAMES*++
*LABWC_DEBUG_MENU_NODENAMES*
Enable logging of all nodenames (for example *policy.placement: Cascade*
for *<placement><policy>Cascade</policy></placement>*) for config and
menu files respectively.

View file

@ -1,3 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<openbox_menu>
<!-- Note: for localization support of menu items "client-menu" has to be removed here -->
<menu id="client-menu">
@ -23,7 +25,18 @@
Any menu with the id "workspaces" will be hidden
if there is only a single workspace available.
-->
<menu id="client-send-to-menu"/>
<menu id="workspaces" label="Workspace">
<item label="Move Left">
<action name="SendToDesktop" to="left" />
</item>
<item label="Move Right">
<action name="SendToDesktop" to="right" />
</item>
<separator />
<item label="Always on Visible Workspace">
<action name="ToggleOmnipresent" />
</item>
</menu>
<!--
openbox default workspace selector
to use replace above workspace menu with the example below
@ -52,17 +65,6 @@
<item label="Exit">
<action name="Exit" />
</item>
<!--
# A prompt can be used as follows:
<item label="Exit">
<action name="If">
<prompt message="Do you really want to exit the compositor?"/>
<then>
<action name="Exit"/>
</then>
</action>
</item>
-->
</menu>
<menu id="some-custom-menu">

View file

@ -1,16 +1,16 @@
scdoc = find_program('scdoc', required: get_option('man-pages'))
if scdoc.found()
manpages = [
'labwc.1',
'labwc-actions.5',
'labwc-config.5',
'labwc-menu.5',
'labwc-theme.5',
'labnag.1',
sections = [
'.1',
'-actions.5',
'-config.5',
'-menu.5',
'-theme.5',
]
foreach manpage : manpages
markdown = manpage + '.scd'
foreach s : sections
markdown = 'labwc' + s + '.scd'
manpage = 'labwc' + s
custom_target(
manpage,
input: markdown,
@ -19,7 +19,7 @@ if scdoc.found()
feed: true,
capture: true,
install: true,
install_dir: join_paths(get_option('mandir'), 'man' + manpage.split('.')[-1])
install_dir: join_paths(get_option('mandir'), 'man' + s.split('.')[-1])
)
endforeach
endif

View file

@ -1,3 +1,5 @@
<?xml version="1.0"?>
<!--
This is a very simple config file with many options missing. For a complete
set of options with comments, see docs/rc.xml.all

View file

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<!--
This file contains all supported config elements & attributes with
default values.
Values for [yes|no] can be replaced by [true|false], [on|off] or [1|0].
-->
<labwc_config>
@ -16,10 +16,6 @@
<reuseOutputMode>no</reuseOutputMode>
<xwaylandPersistence>no</xwaylandPersistence>
<primarySelection>yes</primarySelection>
<!--
# See labwc-config(5) for details
<promptCommand></promptCommand>
-->
</core>
<placement>
@ -42,7 +38,6 @@
</titlebar>
<cornerRadius>8</cornerRadius>
<keepBorder>yes</keepBorder>
<maximizedDecoration>titlebar</maximizedDecoration>
<dropShadows>no</dropShadows>
<dropShadowsOnTiled>no</dropShadowsOnTiled>
<font place="ActiveWindow">
@ -77,8 +72,7 @@
</font>
</theme>
<windowSwitcher show="yes" style="classic" preview="yes"
outlines="yes" allWorkspaces="no" unshade="yes">
<windowSwitcher show="yes" preview="yes" outlines="yes" allWorkspaces="no">
<fields>
<field content="icon" width="5%" />
<field content="desktop_entry_name" width="30%" />
@ -161,7 +155,6 @@
<snapping>
<!-- Set range to 0 to disable window snapping completely -->
<range>10</range>
<cornerRange>50</cornerRange>
<overlay enabled="yes">
<delay inner="500" outer="500" />
</overlay>
@ -274,16 +267,16 @@
<action name="ToggleMaximize" />
</keybind>
<keybind key="W-Left">
<action name="SnapToEdge" direction="left" combine="yes" />
<action name="SnapToEdge" direction="left" />
</keybind>
<keybind key="W-Right">
<action name="SnapToEdge" direction="right" combine="yes" />
<action name="SnapToEdge" direction="right" />
</keybind>
<keybind key="W-Up">
<action name="SnapToEdge" direction="up" combine="yes" />
<action name="SnapToEdge" direction="up" />
</keybind>
<keybind key="W-Down">
<action name="SnapToEdge" direction="down" combine="yes" />
<action name="SnapToEdge" direction="down" />
</keybind>
<keybind key="A-Space">
<action name="ShowMenu" menu="client-menu" atCursor="no" />
@ -378,11 +371,42 @@
</mousebind>
</context>
<context name="Border">
<mousebind button="Left" action="Press">
<action name="Focus" />
<action name="Raise" />
<context name="Top">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="Left">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="Right">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="Bottom">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="TRCorner">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="BRCorner">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="TLCorner">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
</context>
<context name="BLCorner">
<mousebind button="Left" action="Drag">
<action name="Resize" />
</mousebind>
@ -584,13 +608,7 @@
- sendEventsMode [yes|no|disabledOnExternalMouse]
- calibrationMatrix [six float values split by space]
- scrollFactor [float]
The following <libinput>...</libinput> block may not be complete for
your requirements. Default values are device specific. Only set an option
if you require to override the default. Valid values must be inserted.
-->
<libinput>
<device category="default">
<naturalScroll></naturalScroll>

View file

@ -91,27 +91,14 @@ osd.label.text.color: #000000
# width can be set as percent (of screen width)
# example 50% or 75% instead of 600, max 100%
osd.window-switcher.style-classic.width: 600
osd.window-switcher.width: 600
osd.window-switcher.style-classic.padding: 4
osd.window-switcher.style-classic.item.padding.x: 10
osd.window-switcher.style-classic.item.padding.y: 1
osd.window-switcher.style-classic.item.active.border.width: 2
osd.window-switcher.style-classic.item.active.border.color: #706f6d
osd.window-switcher.style-classic.item.active.bg.color: #bfbcba
osd.window-switcher.padding: 4
osd.window-switcher.item.padding.x: 10
osd.window-switcher.item.padding.y: 1
osd.window-switcher.item.active.border.width: 2
# The icon size the same as the font size by default
# osd.window-switcher.style-classic.item.icon.size: 50
osd.window-switcher.style-thumbnail.width.max: 80%
osd.window-switcher.style-thumbnail.padding: 4
osd.window-switcher.style-thumbnail.item.width: 300
osd.window-switcher.style-thumbnail.item.height: 250
osd.window-switcher.style-thumbnail.item.padding: 10
osd.window-switcher.style-thumbnail.item.active.border.width: 2
osd.window-switcher.style-thumbnail.item.active.border.color: #706f6d
osd.window-switcher.style-thumbnail.item.active.bg.color: #bfbcba
osd.window-switcher.style-thumbnail.item.icon.size: 60
# osd.window-switcher.item.icon.size: 50
osd.window-switcher.preview.border.width: 1
osd.window-switcher.preview.border.color: #dddda6,#000000,#dddda6

View file

@ -1,9 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_ACTION_PROMPT_CODES_H
#define LABWC_ACTION_PROMPT_CODES_H
#define LAB_EXIT_FAILURE 255
#define LAB_EXIT_CANCELLED 254
#define LAB_EXIT_SUCCESS 0
#endif /* LABWC_ACTION_PROMPT_CODES_H */

View file

@ -3,7 +3,6 @@
#define LABWC_ACTION_H
#include <stdbool.h>
#include <sys/types.h>
#include <wayland-util.h>
struct view;
@ -23,8 +22,6 @@ struct action {
struct action *action_create(const char *action_name);
const char *action_get_str(struct action *action, const char *key,
const char *default_value);
bool action_is_valid(struct action *action);
bool action_is_show_menu(struct action *action);
@ -50,9 +47,6 @@ bool actions_contain_toggle_keybinds(struct wl_list *action_list);
void actions_run(struct view *activator, struct server *server,
struct wl_list *actions, struct cursor_context *ctx);
void action_prompts_destroy(void);
bool action_check_prompt_result(pid_t pid, int exit_code);
void action_free(struct action *action);
void action_list_free(struct wl_list *action_list);

View file

@ -1,9 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_ARRAY_H
#define LABWC_ARRAY_H
#include <stdio.h>
#include <stdlib.h>
#include <wayland-server-core.h>
#include "common/mem.h"
/*
* Wayland's wl_array API is a bit sparse consisting only of
@ -66,7 +66,10 @@ wl_array_len(struct wl_array *array)
#define array_add(_arr, _val) do { \
__typeof__(_val) *_entry = wl_array_add( \
(_arr), sizeof(__typeof__(_val))); \
die_if_null(_entry); \
if (!_entry) { \
perror("Failed to allocate memory"); \
exit(EXIT_FAILURE); \
} \
*_entry = (_val); \
} while (0)

View file

@ -18,7 +18,7 @@ void box_union(struct wlr_box *box_dest, struct wlr_box *box_a,
* The returned x & y coordinates are the centered content position
* relative to the top-left corner of the bounding box.
*/
struct wlr_box box_fit_within(int width, int height, struct wlr_box *bound);
struct wlr_box box_fit_within(int width, int height, struct wlr_box *bounding_box);
struct wlr_fbox box_to_fbox(struct wlr_box *box);

View file

@ -50,17 +50,6 @@ void buf_expand_shell_variables(struct buf *s);
*/
void buf_add_fmt(struct buf *s, const char *fmt, ...);
/**
* buf_add_hex_color - add rgb color as hex string to C string buffer
* @s: buffer
* @color: rgb color to be added
*
* For example:
* - With the input 'red' (defined as red[4] = { 1.0f, 0.0f, 0.0f, 1.0f}) the
* string "#ff0000ff" will be written to the buffer.
*/
void buf_add_hex_color(struct buf *s, float color[4]);
/**
* buf_add - add data to C string buffer
* @s: buffer
@ -71,9 +60,9 @@ void buf_add(struct buf *s, const char *data);
/**
* buf_add_char - add single char to C string buffer
* @s: buffer
* @ch: char to be added
* @data: char to be added
*/
void buf_add_char(struct buf *s, char ch);
void buf_add_char(struct buf *s, char data);
/**
* buf_clear - clear the buffer, internal allocations are preserved
@ -109,11 +98,4 @@ void buf_reset(struct buf *s);
*/
void buf_move(struct buf *dst, struct buf *src);
/**
* buf_from_file - read file into memory buffer
* @filename: file to read
* Free returned buffer with buf_reset().
*/
struct buf buf_from_file(const char *filename);
#endif /* LABWC_BUF_H */

View file

@ -0,0 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_DIRECTION_H
#define LABWC_DIRECTION_H
#include "view.h"
enum wlr_direction direction_from_view_edge(enum view_edge edge);
enum wlr_direction direction_get_opposite(enum wlr_direction direction);
#endif /* LABWC_DIRECTION_H */

View file

@ -1,81 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_EDGE_H
#define LABWC_EDGE_H
#include <stdbool.h>
/**
* Unified/overloaded enum representing edges, corners, and directions.
* Used in many different contexts (moving, resizing, tiling) and with
* somewhat different semantics depending on context.
*
* Examples:
* - LAB_EDGE_TOP can also mean "up" or "north".
* - LAB_EDGES_TOP_LEFT can mean "top left corner" or "northwest".
*
* The enum is designed to be used as a bitset, and combinations of
* edges typically mean what you'd expect from the context. For example,
* LAB_EDGES_TOP_LEFT is used when resizing a view from its top-left
* corner, or when tiling a view in the top-left corner of an output.
*
* All 16 possible combinations of TOP/BOTTOM/LEFT/RIGHT are listed for
* completeness. Not all combinations make sense in all contexts.
*
* LAB_EDGE_NONE is sometimes used to mean "invalid".
*
* LAB_EDGE_ANY means "any edge or combination of edges (except NONE)"
* and is distinct from LAB_EDGE_ALL (which means all 4 edges).
*
* LAB_EDGE_TOP/BOTTOM/LEFT/RIGHT match the corresponding values of
* enum wlr_edges and enum wlr_direction, so that conversion between
* enums can be done with a simple cast.
*/
enum lab_edge {
LAB_EDGE_NONE = 0,
LAB_EDGE_TOP = (1 << 0), /* or UP */
LAB_EDGE_BOTTOM = (1 << 1), /* or DOWN */
LAB_EDGE_LEFT = (1 << 2),
LAB_EDGE_RIGHT = (1 << 3),
LAB_EDGE_CENTER = (1 << 4), /* for window tiling */
LAB_EDGE_ANY = (1 << 5), /* for window rules */
/* corners or ordinal directions (NW/NE/SW/SE) */
LAB_EDGES_TOP_LEFT = (LAB_EDGE_TOP | LAB_EDGE_LEFT),
LAB_EDGES_TOP_RIGHT = (LAB_EDGE_TOP | LAB_EDGE_RIGHT),
LAB_EDGES_BOTTOM_LEFT = (LAB_EDGE_BOTTOM | LAB_EDGE_LEFT),
LAB_EDGES_BOTTOM_RIGHT = (LAB_EDGE_BOTTOM | LAB_EDGE_RIGHT),
/* opposite edges */
LAB_EDGES_TOP_BOTTOM = (LAB_EDGE_TOP | LAB_EDGE_BOTTOM),
LAB_EDGES_LEFT_RIGHT = (LAB_EDGE_LEFT | LAB_EDGE_RIGHT),
/* all 4 edges */
LAB_EDGES_ALL = (LAB_EDGE_TOP | LAB_EDGE_BOTTOM |
LAB_EDGE_LEFT | LAB_EDGE_RIGHT),
/* 3-edge combinations (for completeness) */
LAB_EDGES_EXCEPT_TOP = (LAB_EDGES_ALL ^ LAB_EDGE_TOP),
LAB_EDGES_EXCEPT_BOTTOM = (LAB_EDGES_ALL ^ LAB_EDGE_BOTTOM),
LAB_EDGES_EXCEPT_LEFT = (LAB_EDGES_ALL ^ LAB_EDGE_LEFT),
LAB_EDGES_EXCEPT_RIGHT = (LAB_EDGES_ALL ^ LAB_EDGE_RIGHT),
};
enum lab_edge lab_edge_parse(const char *direction, bool tiled, bool any);
/**
* Returns true if edge is TOP, BOTTOM, LEFT, or RIGHT
* (i.e. one of the four cardinal directions N/S/W/E)
*/
bool lab_edge_is_cardinal(enum lab_edge edge);
/**
* lab_edge_invert() - select the opposite of a provided edge
*
* Returns LAB_EDGE_NONE for edges other than TOP/BOTTOM/LEFT/RIGHT.
*
* @edge: edge to be inverted
*/
enum lab_edge lab_edge_invert(enum lab_edge edge);
#endif /* LABWC_EDGE_H */

View file

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Read file into memory
*
* Copyright Johan Malm 2020
*/
#ifndef LABWC_GRAB_FILE_H
#define LABWC_GRAB_FILE_H
#include "common/buf.h"
/**
* grab_file - read file into memory buffer
* @filename: file to read
* Free returned buffer with buf_reset().
*/
struct buf grab_file(const char *filename);
#endif /* LABWC_GRAB_FILE_H */

View file

@ -2,8 +2,6 @@
#ifndef LABWC_GRAPHIC_HELPERS_H
#define LABWC_GRAPHIC_HELPERS_H
#include <stdbool.h>
#include <stdint.h>
#include <cairo.h>
struct wlr_fbox;

View file

@ -4,12 +4,6 @@
#include <stdlib.h>
/*
* If ptr is NULL, prints an error (based on errno) and exits.
* Suitable for checking the return value of malloc() etc.
*/
void die_if_null(void *ptr);
/*
* As defined in busybox, weston, etc.
* Allocates zero-filled memory; calls exit() on error.

View file

@ -1,75 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_NODE_TYPE_H
#define LABWC_NODE_TYPE_H
#include "common/edge.h"
/*
* In labwc, "node type" indicates the role of a wlr_scene_node in the
* overall desktop. It also maps more-or-less to the openbox concept of
* "context" (as used when defining mouse bindings).
*
* Some types (BUTTON, BORDER, etc.) refer to groups or categories of
* other node types rather than individual nodes. These categories are
* defined as ranges (e.g. BUTTON means anything from BUTTON_FIRST to
* BUTTON_LAST), therefore order is significant.
*
* Be sure to keep node_type_contains() in sync with any changes!
*/
enum lab_node_type {
LAB_NODE_NONE = 0,
LAB_NODE_BUTTON_CLOSE = 1,
LAB_NODE_BUTTON_MAXIMIZE,
LAB_NODE_BUTTON_ICONIFY,
LAB_NODE_BUTTON_WINDOW_ICON,
LAB_NODE_BUTTON_WINDOW_MENU,
LAB_NODE_BUTTON_SHADE,
LAB_NODE_BUTTON_OMNIPRESENT,
LAB_NODE_BUTTON_FIRST = LAB_NODE_BUTTON_CLOSE,
LAB_NODE_BUTTON_LAST = LAB_NODE_BUTTON_OMNIPRESENT,
LAB_NODE_BUTTON,
LAB_NODE_TITLEBAR,
LAB_NODE_TITLE,
LAB_NODE_CORNER_TOP_LEFT,
LAB_NODE_CORNER_TOP_RIGHT,
LAB_NODE_CORNER_BOTTOM_RIGHT,
LAB_NODE_CORNER_BOTTOM_LEFT,
LAB_NODE_BORDER_TOP,
LAB_NODE_BORDER_RIGHT,
LAB_NODE_BORDER_BOTTOM,
LAB_NODE_BORDER_LEFT,
LAB_NODE_BORDER,
LAB_NODE_CLIENT,
LAB_NODE_FRAME,
LAB_NODE_ROOT,
LAB_NODE_MENUITEM,
LAB_NODE_OSD,
LAB_NODE_LAYER_SURFACE,
LAB_NODE_UNMANAGED,
LAB_NODE_ALL,
/* translated to LAB_NODE_CLIENT by get_cursor_context() */
LAB_NODE_VIEW,
LAB_NODE_XDG_POPUP,
LAB_NODE_LAYER_POPUP,
LAB_NODE_SESSION_LOCK_SURFACE,
LAB_NODE_IME_POPUP,
/*
* translated to LAB_CORNER_* or LAB_BORDER* by
* ssd_get_resizing_type()
*/
LAB_NODE_SSD_ROOT,
};
enum lab_node_type node_type_parse(const char *context);
bool node_type_contains(enum lab_node_type whole, enum lab_node_type part);
enum lab_edge node_type_to_edges(enum lab_node_type type);
#endif /* LABWC_NODE_TYPE_H */

View file

@ -4,6 +4,7 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <stdio.h>
/**
* nodename - give xml node an ascii name

View file

@ -1,18 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_PARSE_BOOL_H
#define LABWC_PARSE_BOOL_H
#include <stdbool.h>
#include "config/types.h"
#include "common/three-state.h"
/**
* parse_tristate() - Parse boolean value of string as a three-state enum.
* parse_three_state() - Parse boolean value of string as a three-state enum.
* @string: String to interpret. This check is case-insensitive.
*
* Return: LAB_STATE_DISABLED for false; LAB_STATE_ENABLED for true;
* LAB_STATE_UNSPECIFIED for non-boolean
*/
enum lab_tristate parse_tristate(const char *str);
enum three_state parse_three_state(const char *str);
/**
* parse_bool() - Parse boolean value of string.

View file

@ -6,7 +6,7 @@
struct wlr_scene_tree;
struct wlr_scene_buffer;
struct scaled_buffer;
struct scaled_scene_buffer;
struct scaled_font_buffer {
struct wlr_scene_buffer *scene_buffer;
@ -19,7 +19,7 @@ struct scaled_font_buffer {
float color[4];
float bg_color[4];
struct font font;
struct scaled_buffer *scaled_buffer;
struct scaled_scene_buffer *scaled_buffer;
/*
* The following fields are used only for the titlebar, where
@ -34,7 +34,7 @@ struct scaled_font_buffer {
/**
* Create an auto scaling font buffer, providing a wlr_scene_buffer node for
* display. It gets destroyed automatically when the backing scaled_buffer
* display. It gets destroyed automatically when the backing scaled_scene_buffer
* is being destroyed which in turn happens automatically when the backing
* wlr_scene_buffer (or one of its parents) is being destroyed.
*
@ -73,4 +73,12 @@ void scaled_font_buffer_update(struct scaled_font_buffer *self, const char *text
int max_width, struct font *font, const float *color,
const float *bg_color);
/**
* Update the max width of an existing auto scaling font buffer
* and force a new render.
*
* No steps are taken to detect if its actually required to render a new buffer.
*/
void scaled_font_buffer_set_max_width(struct scaled_font_buffer *self, int max_width);
#endif /* LABWC_SCALED_FONT_BUFFER_H */

View file

@ -10,7 +10,7 @@ struct wlr_scene_node;
struct wlr_scene_buffer;
struct scaled_icon_buffer {
struct scaled_buffer *scaled_buffer;
struct scaled_scene_buffer *scaled_buffer;
struct wlr_scene_buffer *scene_buffer;
struct server *server;
/* for window icon */
@ -34,7 +34,7 @@ struct scaled_icon_buffer {
/*
* Create an auto scaling icon buffer, providing a wlr_scene_buffer node for
* display. It gets destroyed automatically when the backing scaled_buffer
* display. It gets destroyed automatically when the backing scaled_scene_buffer
* is being destroyed which in turn happens automatically when the backing
* wlr_scene_buffer (or one of its parents) is being destroyed.
*/
@ -48,4 +48,7 @@ void scaled_icon_buffer_set_view(struct scaled_icon_buffer *self,
void scaled_icon_buffer_set_icon_name(struct scaled_icon_buffer *self,
const char *icon_name);
/* Obtain scaled_icon_buffer from wlr_scene_node */
struct scaled_icon_buffer *scaled_icon_buffer_from_node(struct wlr_scene_node *node);
#endif /* LABWC_SCALED_ICON_BUFFER_H */

View file

@ -2,13 +2,15 @@
#ifndef LABWC_SCALED_IMG_BUFFER_H
#define LABWC_SCALED_IMG_BUFFER_H
#include <stdbool.h>
struct wlr_scene_tree;
struct wlr_scene_node;
struct wlr_scene_buffer;
struct lab_img;
struct scaled_img_buffer {
struct scaled_buffer *scaled_buffer;
struct scaled_scene_buffer *scaled_buffer;
struct wlr_scene_buffer *scene_buffer;
struct lab_img *img;
int width;
@ -54,7 +56,7 @@ struct scaled_img_buffer {
/*
* Create an auto scaling image buffer, providing a wlr_scene_buffer node for
* display. It gets destroyed automatically when the backing scaled_buffer
* display. It gets destroyed automatically when the backing scaled_scene_buffer
* is being destroyed which in turn happens automatically when the backing
* wlr_scene_buffer (or one of its parents) is being destroyed.
*
@ -64,4 +66,7 @@ struct scaled_img_buffer {
struct scaled_img_buffer *scaled_img_buffer_create(struct wlr_scene_tree *parent,
struct lab_img *img, int width, int height);
/* Obtain scaled_img_buffer from wlr_scene_node */
struct scaled_img_buffer *scaled_img_buffer_from_node(struct wlr_scene_node *node);
#endif /* LABWC_SCALED_IMG_BUFFER_H */

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_SCALED_BUFFER_H
#define LABWC_SCALED_BUFFER_H
#ifndef LABWC_SCALED_SCENE_BUFFER_H
#define LABWC_SCALED_SCENE_BUFFER_H
#include <wayland-server-core.h>
@ -9,20 +9,20 @@
struct wlr_buffer;
struct wlr_scene_tree;
struct lab_data_buffer;
struct scaled_buffer;
struct scaled_scene_buffer;
struct scaled_buffer_impl {
struct scaled_scene_buffer_impl {
/* Return a new buffer optimized for the new scale */
struct lab_data_buffer *(*create_buffer)
(struct scaled_buffer *scaled_buffer, double scale);
(struct scaled_scene_buffer *scaled_buffer, double scale);
/* Might be NULL or used for cleaning up */
void (*destroy)(struct scaled_buffer *scaled_buffer);
void (*destroy)(struct scaled_scene_buffer *scaled_buffer);
/* Returns true if the two buffers are visually the same */
bool (*equal)(struct scaled_buffer *scaled_buffer_a,
struct scaled_buffer *scaled_buffer_b);
bool (*equal)(struct scaled_scene_buffer *scaled_buffer_a,
struct scaled_scene_buffer *scaled_buffer_b);
};
struct scaled_buffer {
struct scaled_scene_buffer {
struct wlr_scene_buffer *scene_buffer;
int width; /* unscaled, read only */
int height; /* unscaled, read only */
@ -35,7 +35,7 @@ struct scaled_buffer {
struct wl_list cache; /* struct scaled_buffer_cache_entry.link */
struct wl_listener destroy;
struct wl_listener outputs_update;
const struct scaled_buffer_impl *impl;
const struct scaled_scene_buffer_impl *impl;
struct wl_list link; /* all_scaled_buffers */
};
@ -78,22 +78,22 @@ struct scaled_buffer {
* to handle the majority of use cases where a view is moved between no more
* than two different scales.
*
* scaled_buffer will clean up automatically once the internal
* scaled_scene_buffer will clean up automatically once the internal
* wlr_scene_buffer is being destroyed. If implementation->destroy is set
* it will also get called so a consumer of this API may clean up its own
* allocations.
*
* Besides caching buffers for each scale per scaled_buffer, we also
* store all the scaled_buffers from all the implementers in a list
* Besides caching buffers for each scale per scaled_scene_buffer, we also
* store all the scaled_scene_buffers from all the implementers in a list
* in order to reuse backing buffers for visually duplicated
* scaled_buffers found via impl->equal().
* scaled_scene_buffers found via impl->equal().
*
* All requested lab_data_buffers via impl->create_buffer() will be locked
* during the lifetime of the buffer in the internal cache and unlocked
* when being evacuated from the cache (due to LAB_SCALED_BUFFER_MAX_CACHE
* or the internal wlr_scene_buffer being destroyed).
*
* If drop_buffer was set during creation of the scaled_buffer, the
* If drop_buffer was set during creation of the scaled_scene_buffer, the
* backing wlr_buffer behind a lab_data_buffer will also get dropped
* (via wlr_buffer_drop). If there are no more locks (consumers) of the
* respective buffer this will then cause the lab_data_buffer to be free'd.
@ -103,21 +103,21 @@ struct scaled_buffer {
* destroyed until the buffer is evacuated from the internal cache and thus
* unlocked.
*
* This allows using scaled_buffer for an autoscaling font_buffer
* This allows using scaled_scene_buffer for an autoscaling font_buffer
* (which gets free'd automatically) and also for theme components like
* rounded corner images or button icons whose buffers only exist once but
* are references by multiple windows with their own scaled_buffers.
* are references by multiple windows with their own scaled_scene_buffers.
*
* The rough idea is: use drop_buffer = true for one-shot buffers and false
* for buffers that should outlive the scaled_buffer instance itself.
* for buffers that should outlive the scaled_scene_buffer instance itself.
*/
struct scaled_buffer *scaled_buffer_create(
struct scaled_scene_buffer *scaled_scene_buffer_create(
struct wlr_scene_tree *parent,
const struct scaled_buffer_impl *implementation,
const struct scaled_scene_buffer_impl *implementation,
bool drop_buffer);
/**
* scaled_buffer_request_update - mark the buffer that needs to be
* scaled_scene_buffer_request_update - mark the buffer that needs to be
* updated
* @width: the width of the buffer to be rendered, in scene coordinates
* @height: the height of the buffer to be rendered, in scene coordinates
@ -125,22 +125,22 @@ struct scaled_buffer *scaled_buffer_create(
* This function should be called when the states bound to the buffer are
* updated and ready for rendering.
*/
void scaled_buffer_request_update(struct scaled_buffer *self,
void scaled_scene_buffer_request_update(struct scaled_scene_buffer *self,
int width, int height);
/**
* scaled_buffer_invalidate_sharing - clear the list of entire cached
* scaled_buffers used to share visually dupliated buffers. This should
* scaled_scene_buffer_invalidate_sharing - clear the list of entire cached
* scaled_scene_buffers used to share visually dupliated buffers. This should
* be called on Reconfigure to force updates of newly created
* scaled_buffers rather than reusing ones created before Reconfigure.
* scaled_scene_buffers rather than reusing ones created before Reconfigure.
*/
void scaled_buffer_invalidate_sharing(void);
void scaled_scene_buffer_invalidate_sharing(void);
/* Private */
struct scaled_buffer_cache_entry {
struct wl_list link; /* struct scaled_buffer.cache */
struct scaled_scene_buffer_cache_entry {
struct wl_list link; /* struct scaled_scene_buffer.cache */
struct wlr_buffer *buffer;
double scale;
};
#endif /* LABWC_SCALED_BUFFER_H */
#endif /* LABWC_SCALED_SCENE_BUFFER_H */

View file

@ -20,6 +20,6 @@ struct wlr_scene_node *lab_wlr_scene_get_prev_node(struct wlr_scene_node *node);
/* A variant of wlr_scene_output_commit() that respects wlr_output->pending */
bool lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output,
struct wlr_output_state *state);
struct wlr_output_state *output_state);
#endif /* LABWC_SCENE_HELPERS_H */

View file

@ -10,10 +10,13 @@
bool string_null_or_empty(const char *s);
/**
* str_space_only - Check if the string only contains white-space characters
* @s: string to check
* trim_last_field() - Trim last field of string splitting on provided delim
* @buf: string to trim
* @delim: delimitator
*
* Example: With delim='_' and buf="foo_bar_baz" the return value is "foo_bar"
*/
bool str_space_only(const char *s);
void trim_last_field(char *buf, char delim);
/**
* string_strip - strip white space left and right
@ -56,7 +59,8 @@ char *strdup_printf(const char *fmt, ...);
* The separator is arbitrary. When the separator is NULL, a single space will
* be used.
*/
char *str_join(const char *const parts[], const char *fmt, const char *sep);
char *str_join(const char *const parts[],
const char *restrict fmt, const char *restrict sep);
/**
* str_endswith - indicate whether a string ends with a given suffix

View file

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_SURFACE_HELPERS_H
#define LABWC_SURFACE_HELPERS_H
struct wlr_surface;
struct wlr_layer_surface_v1;
/**
* subsurface_parent_layer() - Get wlr_layer_surface from layer-subsurface
* @wlr_surface: The wlr_surface of the wlr_subsurface for which to get the
* layer-surface.
*/
struct wlr_layer_surface_v1 *subsurface_parent_layer(
struct wlr_surface *wlr_surface);
#endif /* LABWC_SURFACE_HELPERS_H */

View file

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_THREE_STATE_H
#define LABWC_THREE_STATE_H
enum three_state {
LAB_STATE_UNSPECIFIED = 0,
LAB_STATE_ENABLED,
LAB_STATE_DISABLED
};
#endif /* LABWC_THREE_STATE_H */

View file

@ -1,66 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_XML_H
#define LABWC_XML_H
#include <libxml/tree.h>
#include <stdbool.h>
/*
* Converts dotted attributes into nested nodes.
* For example, the following node:
*
* <keybind name.action="ShowMenu" menu.action="root-menu"
* x.position.action="1" y.position.action="2" />
*
* is converted to:
*
* <keybind>
* <action>
* <name>ShowMenu</name>
* <menu>root-menu</menu>
* <position>
* <x>1</x>
* <y>2</y>
* </position>
* </action>
* </keybind>
*/
void lab_xml_expand_dotted_attributes(xmlNode *parent);
/* Returns true if the node only contains a string or is empty */
bool lab_xml_node_is_leaf(xmlNode *node);
bool lab_xml_get_string(xmlNode *node, const char *key, char *s, size_t len);
bool lab_xml_get_int(xmlNode *node, const char *key, int *i);
bool lab_xml_get_bool(xmlNode *node, const char *key, bool *b);
/* also skips other unusual nodes like comments */
static inline xmlNode *
lab_xml_skip_text(xmlNode *child)
{
while (child && child->type != XML_ELEMENT_NODE) {
child = child->next;
}
return child;
}
static inline void
lab_xml_get_key_and_content(xmlNode *node, char **name, char **content)
{
if (node) {
*name = (char *)node->name;
*content = (char *)xmlNodeGetContent(node);
}
}
#define LAB_XML_FOR_EACH(parent, child, key, content) \
for ((child) = lab_xml_skip_text((parent)->children), \
lab_xml_get_key_and_content((child), &(key), &(content)); \
\
(child); \
\
xmlFree((xmlChar *)(content)), \
(child) = lab_xml_skip_text((child)->next), \
lab_xml_get_key_and_content((child), &(key), &(content)))
#endif /* LABWC_XML_H */

View file

@ -35,10 +35,6 @@ static struct key_combos {
.name = "direction",
.value = "left",
},
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, {
.binding = "W-Right",
.action = "SnapToEdge",
@ -46,10 +42,6 @@ static struct key_combos {
.name = "direction",
.value = "right",
},
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, {
.binding = "W-Up",
.action = "SnapToEdge",
@ -57,10 +49,6 @@ static struct key_combos {
.name = "direction",
.value = "up",
},
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, {
.binding = "W-Down",
.action = "SnapToEdge",
@ -68,10 +56,6 @@ static struct key_combos {
.name = "direction",
.value = "down",
},
.attributes[1] = {
.name = "combine",
.value = "yes",
},
}, {
.binding = "A-Space",
.action = "ShowMenu",
@ -159,17 +143,42 @@ static struct mouse_combos {
const char *name, *value;
} attributes[2];
} mouse_combos[] = { {
.context = "Border",
.context = "Left",
.button = "Left",
.event = "Press",
.action = "Focus",
.event = "Drag",
.action = "Resize",
}, {
.context = "Border",
.context = "Top",
.button = "Left",
.event = "Press",
.action = "Raise",
.event = "Drag",
.action = "Resize",
}, {
.context = "Border",
.context = "Bottom",
.button = "Left",
.event = "Drag",
.action = "Resize",
}, {
.context = "Right",
.button = "Left",
.event = "Drag",
.action = "Resize",
}, {
.context = "TLCorner",
.button = "Left",
.event = "Drag",
.action = "Resize",
}, {
.context = "TRCorner",
.button = "Left",
.event = "Drag",
.action = "Resize",
}, {
.context = "BRCorner",
.button = "Left",
.event = "Drag",
.action = "Resize",
}, {
.context = "BLCorner",
.button = "Left",
.event = "Drag",
.action = "Resize",

View file

@ -2,8 +2,7 @@
#ifndef LABWC_KEYBIND_H
#define LABWC_KEYBIND_H
#include <stdbool.h>
#include <wayland-util.h>
#include <wlr/types/wlr_keyboard.h>
#include <xkbcommon/xkbcommon.h>
#define MAX_KEYSYMS 32
@ -42,8 +41,5 @@ uint32_t parse_modifier(const char *symname);
bool keybind_the_same(struct keybind *a, struct keybind *b);
bool keybind_contains_keycode(struct keybind *keybind, xkb_keycode_t keycode);
bool keybind_contains_keysym(struct keybind *keybind, xkb_keysym_t keysym);
void keybind_update_keycodes(struct server *server);
#endif /* LABWC_KEYBIND_H */

View file

@ -38,7 +38,6 @@ struct libinput_category {
};
enum lab_libinput_device_type get_device_type(const char *s);
const char *libinput_device_type_name(enum lab_libinput_device_type type);
struct libinput_category *libinput_category_create(void);
struct libinput_category *libinput_category_get_default(void);

View file

@ -2,9 +2,9 @@
#ifndef LABWC_MOUSEBIND_H
#define LABWC_MOUSEBIND_H
#include <stdbool.h>
#include <wayland-util.h>
#include "common/node-type.h"
#include "ssd.h"
#include "config/keybind.h"
enum mouse_event {
MOUSE_ACTION_NONE = 0,
@ -25,7 +25,7 @@ enum direction {
};
struct mousebind {
enum lab_node_type context;
enum ssd_part_type context;
/* ex: BTN_LEFT, BTN_RIGHT from linux/input_event_codes.h */
uint32_t button;

View file

@ -3,19 +3,28 @@
#define LABWC_RCXML_H
#include <stdbool.h>
#include <stdio.h>
#include <wayland-server-core.h>
#include <wlr/util/box.h>
#include <libxml/tree.h>
#include "common/border.h"
#include "common/buf.h"
#include "common/font.h"
#include "common/node-type.h"
#include "config/types.h"
#include "common/three-state.h"
#include "config/touch.h"
#include "config/tablet.h"
#include "config/tablet-tool.h"
#include "config/libinput.h"
#include "resize-indicator.h"
#include "ssd.h"
#include "theme.h"
#define BUTTON_MAP_MAX 16
/* max of one button of each type (no repeats) */
#define TITLE_BUTTONS_MAX ((LAB_NODE_BUTTON_LAST + 1) - LAB_NODE_BUTTON_FIRST)
enum view_placement_policy {
LAB_PLACE_INVALID = 0,
LAB_PLACE_CENTER,
LAB_PLACE_CURSOR,
LAB_PLACE_AUTOMATIC,
LAB_PLACE_CASCADE,
};
enum adaptive_sync_mode {
LAB_ADAPTIVE_SYNC_DISABLED,
@ -23,12 +32,6 @@ enum adaptive_sync_mode {
LAB_ADAPTIVE_SYNC_FULLSCREEN,
};
enum resize_indicator_mode {
LAB_RESIZE_INDICATOR_NEVER = 0,
LAB_RESIZE_INDICATOR_ALWAYS,
LAB_RESIZE_INDICATOR_NON_PIXEL
};
enum tearing_mode {
LAB_TEARING_DISABLED = 0,
LAB_TEARING_ENABLED,
@ -44,11 +47,9 @@ enum tiling_events_mode {
(LAB_TILING_EVENTS_REGION | LAB_TILING_EVENTS_EDGE),
};
struct buf;
struct button_map_entry {
uint32_t from;
uint32_t to;
struct title_button {
enum ssd_part_type type;
struct wl_list link;
};
struct usable_area_override {
@ -65,18 +66,14 @@ struct rcxml {
/* core */
bool xdg_shell_server_side_deco;
bool hide_maximized_window_titlebar;
int gap;
enum adaptive_sync_mode adaptive_sync;
enum tearing_mode allow_tearing;
bool auto_enable_outputs;
bool reuse_output_mode;
enum view_placement_policy placement_policy;
bool xwayland_persistence;
bool primary_selection;
char *prompt_command;
/* placement */
enum lab_placement_policy placement_policy;
int placement_cascade_offset_x;
int placement_cascade_offset_y;
@ -89,12 +86,8 @@ struct rcxml {
char *theme_name;
char *icon_theme_name;
char *fallback_app_icon_name;
enum lab_node_type title_buttons_left[TITLE_BUTTONS_MAX];
int nr_title_buttons_left;
enum lab_node_type title_buttons_right[TITLE_BUTTONS_MAX];
int nr_title_buttons_right;
struct wl_list title_buttons_left;
struct wl_list title_buttons_right;
int corner_radius;
bool show_title;
bool title_layout_loaded;
@ -116,7 +109,7 @@ struct rcxml {
/* keyboard */
int repeat_rate;
int repeat_delay;
enum lab_tristate kb_numlock_enable;
enum three_state kb_numlock_enable;
bool kb_layout_per_window;
struct wl_list keybinds; /* struct keybind.link */
@ -132,12 +125,12 @@ struct rcxml {
bool force_mouse_emulation;
char *output_name;
struct wlr_fbox box;
enum lab_rotation rotation;
enum rotation rotation;
uint16_t button_map_count;
struct button_map_entry button_map[BUTTON_MAP_MAX];
} tablet;
struct tablet_tool_config {
enum lab_motion motion;
enum motion motion;
double relative_motion_sensitivity;
} tablet_tool;
@ -152,7 +145,6 @@ struct rcxml {
/* window snapping */
int snap_edge_range;
int snap_edge_corner_range;
bool snap_overlay_enabled;
int snap_overlay_delay_inner;
int snap_overlay_delay_outer;
@ -179,10 +171,8 @@ struct rcxml {
bool show;
bool preview;
bool outlines;
bool unshade;
enum lab_view_criteria criteria;
uint32_t criteria;
struct wl_list fields; /* struct window_switcher_field.link */
enum window_switcher_style style;
} window_switcher;
struct wl_list window_rules; /* struct window_rule.link */
@ -201,13 +191,8 @@ struct rcxml {
extern struct rcxml rc;
void rcxml_parse_xml(struct buf *b);
void rcxml_read(const char *filename);
void rcxml_finish(void);
/*
* Parse the child <action> nodes and append them to the list.
* FIXME: move this function to somewhere else.
*/
void append_parsed_actions(xmlNode *node, struct wl_list *list);
#endif /* LABWC_RCXML_H */

View file

@ -2,8 +2,13 @@
#ifndef LABWC_TABLET_TOOL_CONFIG_H
#define LABWC_TABLET_TOOL_CONFIG_H
#include "config/types.h"
#include <stdint.h>
enum lab_motion tablet_parse_motion(const char *name);
enum motion {
LAB_TABLET_MOTION_ABSOLUTE = 0,
LAB_TABLET_MOTION_RELATIVE,
};
enum motion tablet_parse_motion(const char *name);
#endif /* LABWC_TABLET_TOOL_CONFIG_H */

View file

@ -3,10 +3,22 @@
#define LABWC_TABLET_CONFIG_H
#include <stdint.h>
#include "config/types.h"
enum rotation {
LAB_ROTATE_NONE = 0,
LAB_ROTATE_90,
LAB_ROTATE_180,
LAB_ROTATE_270,
};
#define BUTTON_MAP_MAX 16
struct button_map_entry {
uint32_t from;
uint32_t to;
};
double tablet_get_dbl_if_positive(const char *content, const char *name);
enum lab_rotation tablet_parse_rotation(int value);
enum rotation tablet_parse_rotation(int value);
uint32_t tablet_button_from_str(const char *button);
void tablet_button_mapping_add(uint32_t from, uint32_t to);
void tablet_load_default_button_mappings(void);

View file

@ -2,7 +2,7 @@
#ifndef LABWC_TOUCH_CONFIG_H
#define LABWC_TOUCH_CONFIG_H
#include <stdbool.h>
#include <stdint.h>
#include <wayland-util.h>
struct touch_config_entry {

View file

@ -1,115 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_CONFIG_TYPES_H
#define LABWC_CONFIG_TYPES_H
/*
* Shared (basic) types related to user configuration.
*
* Please try to keep dependencies on other headers minimal,
* since config/types.h gets included in many source files.
*
* For the full config struct, see config/rcxml.h.
*/
/**
* Indicates whether tablet tool motion events should be reported using
* absolute or relative coordinates
*/
enum lab_motion {
LAB_MOTION_ABSOLUTE = 0,
LAB_MOTION_RELATIVE,
};
enum lab_placement_policy {
LAB_PLACE_INVALID = 0,
LAB_PLACE_CENTER,
LAB_PLACE_CURSOR,
LAB_PLACE_AUTOMATIC,
LAB_PLACE_CASCADE,
};
enum lab_rotation {
LAB_ROTATE_NONE = 0,
LAB_ROTATE_90,
LAB_ROTATE_180,
LAB_ROTATE_270,
};
enum lab_ssd_mode {
LAB_SSD_MODE_NONE = 0,
LAB_SSD_MODE_BORDER,
LAB_SSD_MODE_FULL,
LAB_SSD_MODE_INVALID,
};
enum lab_tristate {
LAB_STATE_UNSPECIFIED = 0,
LAB_STATE_ENABLED,
LAB_STATE_DISABLED
};
/*
* This enum type is a set of bit flags where each set bit makes the
* criteria more restrictive. For example:
*
* (LAB_VIEW_CRITERIA_FULLSCREEN | LAB_VIEW_CRITERIA_CURRENT_WORKSPACE)
* matches only fullscreen views on the current workspace, while
*
* (LAB_VIEW_CRITERIA_ALWAYS_ON_TOP | LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP)
* would be contradictory and match nothing at all.
*/
enum lab_view_criteria {
/* No filter -> all focusable views */
LAB_VIEW_CRITERIA_NONE = 0,
/*
* Includes always-on-top views, e.g.
* what is visible on the current workspace
*/
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
/* Positive criteria */
LAB_VIEW_CRITERIA_FULLSCREEN = 1 << 1,
LAB_VIEW_CRITERIA_ALWAYS_ON_TOP = 1 << 2,
LAB_VIEW_CRITERIA_ROOT_TOPLEVEL = 1 << 3,
/* Negative criteria */
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 6,
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 7,
LAB_VIEW_CRITERIA_NO_OMNIPRESENT = 1 << 8,
};
/*
* Window types are based on the NET_WM constants from X11. See:
* https://specifications.freedesktop.org/wm-spec/1.4/ar01s05.html#id-1.6.7
*
* The enum constants are intended to match wlr_xwayland_net_wm_window_type.
* Redefining the same constants here may seem redundant, but is necessary
* to make them available even in builds with xwayland support disabled.
*/
enum lab_window_type {
LAB_WINDOW_TYPE_INVALID = -1,
LAB_WINDOW_TYPE_DESKTOP = 0,
LAB_WINDOW_TYPE_DOCK,
LAB_WINDOW_TYPE_TOOLBAR,
LAB_WINDOW_TYPE_MENU,
LAB_WINDOW_TYPE_UTILITY,
LAB_WINDOW_TYPE_SPLASH,
LAB_WINDOW_TYPE_DIALOG,
LAB_WINDOW_TYPE_DROPDOWN_MENU,
LAB_WINDOW_TYPE_POPUP_MENU,
LAB_WINDOW_TYPE_TOOLTIP,
LAB_WINDOW_TYPE_NOTIFICATION,
LAB_WINDOW_TYPE_COMBO,
LAB_WINDOW_TYPE_DND,
LAB_WINDOW_TYPE_NORMAL,
LAB_WINDOW_TYPE_LEN
};
enum window_switcher_style {
WINDOW_SWITCHER_CLASSIC,
WINDOW_SWITCHER_THUMBNAIL,
};
#endif /* LABWC_CONFIG_TYPES_H */

View file

@ -4,7 +4,7 @@
#include <limits.h>
#include <stdbool.h>
#include "common/edge.h"
#include <stdint.h>
#include "common/macros.h"
struct border;
@ -101,6 +101,9 @@ typedef void (*edge_validator_t)(int *best, struct edge current,
void edges_initialize(struct border *edges);
void edges_adjust_geom(struct view *view, struct border edges,
uint32_t resize_edges, struct wlr_box *geom);
void edges_find_neighbors(struct border *nearest_edges, struct view *view,
struct wlr_box origin, struct wlr_box target,
struct output *output, edge_validator_t validator, bool ignore_hidden);
@ -113,10 +116,9 @@ void edges_adjust_move_coords(struct view *view, struct border edges,
int *x, int *y, bool use_pending);
void edges_adjust_resize_geom(struct view *view, struct border edges,
enum lab_edge resize_edges, struct wlr_box *geom, bool use_pending);
uint32_t resize_edges, struct wlr_box *geom, bool use_pending);
bool edges_traverse_edge(struct edge current, struct edge target, struct edge edge);
void edges_calculate_visibility(struct server *server, struct view *ignored_view);
#endif /* LABWC_EDGES_H */

View file

@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_FOREIGN_TOPLEVEL_INTERNAL_H
#define LABWC_FOREIGN_TOPLEVEL_INTERNAL_H
#include <stdbool.h>
#include <wayland-server-core.h>
#include "foreign-toplevel.h"
struct foreign_toplevel {
struct view *view;
/* *-toplevel implementations */
struct wlr_foreign_toplevel {
struct wlr_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener request_maximize;
struct wl_listener request_minimize;
struct wl_listener request_fullscreen;
struct wl_listener request_activate;
struct wl_listener request_close;
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
struct wl_listener new_outputs;
struct wl_listener maximized;
struct wl_listener minimized;
struct wl_listener fullscreened;
struct wl_listener activated;
} on_view;
/* Internal signals */
struct {
struct wl_listener toplevel_parent;
struct wl_listener toplevel_destroy;
} on_foreign_toplevel;
} wlr_toplevel;
struct ext_foreign_toplevel {
struct wlr_ext_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
} on_view;
/* Internal signals */
struct {
struct wl_listener toplevel_destroy;
} on_foreign_toplevel;
} ext_toplevel;
/* TODO: add struct xdg_x11_mapped_toplevel at some point */
struct {
struct wl_signal toplevel_parent; /* struct view *parent */
struct wl_signal toplevel_destroy;
} events;
};
void ext_foreign_toplevel_init(struct foreign_toplevel *toplevel);
void wlr_foreign_toplevel_init(struct foreign_toplevel *toplevel);
void foreign_request_minimize(struct foreign_toplevel *toplevel, bool minimized);
void foreign_request_maximize(struct foreign_toplevel *toplevel, enum view_axis axis);
void foreign_request_fullscreen(struct foreign_toplevel *toplevel, bool fullscreen);
void foreign_request_activate(struct foreign_toplevel *toplevel);
void foreign_request_close(struct foreign_toplevel *toplevel);
#endif /* LABWC_FOREIGN_TOPLEVEL_INTERNAL_H */

View file

@ -1,27 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_EXT_FOREIGN_TOPLEVEL_H
#define LABWC_EXT_FOREIGN_TOPLEVEL_H
#include <wayland-server-core.h>
struct ext_foreign_toplevel {
struct view *view;
struct wlr_ext_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
} on_view;
};
void ext_foreign_toplevel_init(struct ext_foreign_toplevel *ext_toplevel,
struct view *view);
void ext_foreign_toplevel_finish(struct ext_foreign_toplevel *ext_toplevel);
#endif /* LABWC_EXT_FOREIGN_TOPLEVEL_H */

View file

@ -1,39 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_WLR_FOREIGN_TOPLEVEL_H
#define LABWC_WLR_FOREIGN_TOPLEVEL_H
#include <wayland-server-core.h>
struct wlr_foreign_toplevel {
struct view *view;
struct wlr_foreign_toplevel_handle_v1 *handle;
/* Client side events */
struct {
struct wl_listener request_maximize;
struct wl_listener request_minimize;
struct wl_listener request_fullscreen;
struct wl_listener request_activate;
struct wl_listener request_close;
struct wl_listener handle_destroy;
} on;
/* Compositor side state updates */
struct {
struct wl_listener new_app_id;
struct wl_listener new_title;
struct wl_listener new_outputs;
struct wl_listener maximized;
struct wl_listener minimized;
struct wl_listener fullscreened;
struct wl_listener activated;
} on_view;
};
void wlr_foreign_toplevel_init(struct wlr_foreign_toplevel *wlr_toplevel,
struct view *view);
void wlr_foreign_toplevel_set_parent(struct wlr_foreign_toplevel *wlr_toplevel,
struct wlr_foreign_toplevel *parent);
void wlr_foreign_toplevel_finish(struct wlr_foreign_toplevel *wlr_toplevel);
#endif /* LABWC_WLR_FOREIGN_TOPLEVEL_H */

View file

@ -5,7 +5,7 @@
struct wl_display;
struct wlr_seat;
void idle_manager_create(struct wl_display *display);
void idle_manager_create(struct wl_display *display, struct wlr_seat *wlr_seat);
void idle_manager_notify_activity(struct wlr_seat *seat);
#endif /* LABWC_IDLE_H */

View file

@ -4,6 +4,7 @@
#include <cairo.h>
#include <stdbool.h>
#include <stdint.h>
#include <wayland-util.h>
enum lab_img_type {

View file

@ -2,17 +2,16 @@
#ifndef LABWC_CURSOR_H
#define LABWC_CURSOR_H
#include <wayland-server-protocol.h>
#include "common/edge.h"
#include "common/node-type.h"
#include <wlr/types/wlr_cursor.h>
#include <wlr/util/edges.h>
#include "ssd.h"
struct view;
struct seat;
struct server;
struct wlr_input_device;
struct wlr_cursor;
struct wlr_surface;
struct wlr_scene_node;
enum wl_pointer_button_state;
/* Cursors used internally by labwc */
enum lab_cursors {
@ -34,25 +33,35 @@ struct cursor_context {
struct view *view;
struct wlr_scene_node *node;
struct wlr_surface *surface;
enum lab_node_type type;
enum ssd_part_type type;
double sx, sy;
};
/**
* get_cursor_context - find view, surface and scene_node at cursor
* get_cursor_context - find view and scene_node at cursor
*
* If the cursor is on a client-drawn surface:
* - ctx.{surface,node} points to the surface, which may be a subsurface.
* - ctx.view is set if the node is associated to a xdg/x11 window.
* - ctx.type is LAYER_SURFACE or UNMANAGED if the node is a layer-shell
* surface or an X11 unmanaged surface. Otherwise, CLIENT is set.
* Behavior if node points to a surface:
* - If surface is a layer-surface, type will be
* set to LAB_SSD_LAYER_SURFACE and view will be NULL.
*
* If the cursor is on a server-side component (SSD part and menu item):
* - ctx.node points to the root node of that component
* - ctx.view is set if the component is a SSD part
* - ctx.type specifies the component (e.g. MENU_ITEM, BORDER_TOP, BUTTON_ICONIFY)
* - If surface is a 'lost' unmanaged xsurface (one
* with a never-mapped parent view), type will
* be set to LAB_SSD_UNMANAGED and view will be NULL.
*
* 'Lost' unmanaged xsurfaces are usually caused by
* X11 applications opening popups without setting
* the main window as parent. Example: VLC submenus.
*
* - Any other surface will cause type to be set to
* LAB_SSD_CLIENT and return the attached view.
*
* Behavior if node points to internal elements:
* - type will be set to the appropriate enum value
* and view will be NULL if the node is not part of the SSD.
*
* If no node is found for the given layout coordinates,
* type will be set to LAB_SSD_ROOT and view will be NULL.
*
* If no node is found at cursor, ctx.type is set to ROOT.
*/
struct cursor_context get_cursor_context(struct server *server);
@ -76,19 +85,20 @@ void cursor_set_visible(struct seat *seat, bool visible);
* This is mostly important when either resizing a window using a
* keyboard modifier or when using the Resize action from a keybind.
*/
enum lab_edge cursor_get_resize_edges(struct wlr_cursor *cursor,
uint32_t cursor_get_resize_edges(struct wlr_cursor *cursor,
struct cursor_context *ctx);
/**
* cursor_get_from_edge - translate lab_edge enum to lab_cursor enum
* @resize_edges - edge(s) being resized
* cursor_get_from_edge - translate wlroots edge enum to lab_cursor enum
* @resize_edges - WLR_EDGE_ combination like WLR_EDGE_TOP | WLR_EDGE_RIGHT
*
* Returns LAB_CURSOR_DEFAULT on WLR_EDGE_NONE
* Returns the appropriate lab_cursors enum if @resize_edges
* is one of the 4 corners or one of the 4 edges.
*
* Returns LAB_CURSOR_DEFAULT on any other value.
* Asserts on invalid edge combinations like WLR_EDGE_LEFT | WLR_EDGE_RIGHT
*/
enum lab_cursors cursor_get_from_edge(enum lab_edge resize_edges);
enum lab_cursors cursor_get_from_edge(uint32_t resize_edges);
/**
* cursor_update_focus - update cursor focus, may update the cursor icon

View file

@ -3,10 +3,11 @@
#ifndef LABWC_IME_H
#define LABWC_IME_H
#include <wayland-server-core.h>
#include <wlr/types/wlr_text_input_v3.h>
#include <wlr/types/wlr_input_method_v2.h>
#include "labwc.h"
struct keyboard;
struct wlr_keyboard_key_event;
/*
* The relay structure manages the relationship between text-inputs and

View file

@ -2,16 +2,7 @@
#ifndef LABWC_INPUT_H
#define LABWC_INPUT_H
#include <wayland-server-core.h>
struct input {
struct wlr_input_device *wlr_input_device;
struct seat *seat;
/* Set for pointer/touch devices */
double scroll_factor;
struct wl_listener destroy;
struct wl_list link; /* seat.inputs */
};
struct seat;
void input_handlers_init(struct seat *seat);
void input_handlers_finish(struct seat *seat);

View file

@ -24,5 +24,6 @@ void key_state_store_pressed_key_as_bound(uint32_t keycode);
bool key_state_corresponding_press_event_was_bound(uint32_t keycode);
void key_state_bound_key_remove(uint32_t keycode);
int key_state_nr_bound_keys(void);
int key_state_nr_pressed_keys(void);
#endif /* LABWC_KEY_STATE_H */

View file

@ -4,25 +4,10 @@
#include <stdbool.h>
#include <xkbcommon/xkbcommon.h>
#include "input/input.h"
/*
* Virtual keyboards should not belong to seat->keyboard_group. As a result we
* need to be able to ascertain which wlr_keyboard key/modifier events come from
* and we achieve that by using `struct keyboard` which inherits `struct input`
* and adds keyboard specific listeners and a wlr_keyboard pointer.
*/
struct keyboard {
struct input base;
struct wlr_keyboard *wlr_keyboard;
bool is_virtual;
struct wl_listener modifiers;
struct wl_listener key;
/* key repeat for compositor keybinds */
uint32_t keybind_repeat_keycode;
int32_t keybind_repeat_rate;
struct wl_event_source *keybind_repeat;
};
struct seat;
struct keyboard;
struct wlr_keyboard;
void keyboard_reset_current_keybind(void);
void keyboard_configure(struct seat *seat, struct wlr_keyboard *kb,

View file

@ -3,6 +3,7 @@
#define LABWC_TABLET_PAD_H
#include <wayland-server-core.h>
#include <wlr/types/wlr_tablet_v2.h>
struct seat;
struct wlr_device;

View file

@ -3,7 +3,7 @@
#define LABWC_TABLET_H
#include <wayland-server-core.h>
#include "config/types.h"
#include <wlr/types/wlr_tablet_v2.h>
struct seat;
struct wlr_device;
@ -20,7 +20,7 @@ struct drawing_tablet_tool {
*/
bool force_mouse_emulation;
enum lab_motion motion_mode;
enum motion motion_mode;
double x, y, dx, dy;
double distance;
double pressure;

View file

@ -2,17 +2,64 @@
#ifndef LABWC_H
#define LABWC_H
#include "config.h"
#include <wlr/util/box.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <wayland-server-core.h>
#include <wlr/backend.h>
#include <wlr/render/allocator.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_gamma_control_v1.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_keyboard.h>
#include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_power_management_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/types/wlr_pointer.h>
#include <wlr/types/wlr_pointer_constraints_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_subcompositor.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include <wlr/types/wlr_xdg_activation_v1.h>
#include <wlr/types/wlr_xdg_shell.h>
#include <wlr/types/wlr_drm_lease_v1.h>
#include <wlr/types/wlr_virtual_pointer_v1.h>
#include <wlr/types/wlr_virtual_keyboard_v1.h>
#include <wlr/types/wlr_tearing_control_v1.h>
#include <wlr/types/wlr_text_input_v3.h>
#include <wlr/types/wlr_input_method_v2.h>
#include <wlr/types/wlr_tablet_v2.h>
#include <wlr/util/log.h>
#include "common/set.h"
#include "config/keybind.h"
#include "config/rcxml.h"
#include "input/cursor.h"
#include "overlay.h"
#include "regions.h"
#include "session-lock.h"
#if HAVE_NLS
#include <libintl.h>
#include <locale.h>
#define _ gettext
#else
#define _(s) (s)
#endif
#define XCURSOR_DEFAULT "left_ptr"
#define XCURSOR_SIZE 24
struct wlr_xdg_popup;
enum input_mode {
LAB_INPUT_STATE_PASSTHROUGH = 0,
LAB_INPUT_STATE_MOVE,
@ -21,6 +68,33 @@ enum input_mode {
LAB_INPUT_STATE_WINDOW_SWITCHER,
};
struct input {
struct wlr_input_device *wlr_input_device;
struct seat *seat;
/* Set for pointer/touch devices */
double scroll_factor;
struct wl_listener destroy;
struct wl_list link; /* seat.inputs */
};
/*
* Virtual keyboards should not belong to seat->keyboard_group. As a result we
* need to be able to ascertain which wlr_keyboard key/modifier events come from
* and we achieve that by using `struct keyboard` which inherits `struct input`
* and adds keyboard specific listeners and a wlr_keyboard pointer.
*/
struct keyboard {
struct input base;
struct wlr_keyboard *wlr_keyboard;
bool is_virtual;
struct wl_listener modifiers;
struct wl_listener key;
/* key repeat for compositor keybinds */
uint32_t keybind_repeat_keycode;
int32_t keybind_repeat_rate;
struct wl_event_source *keybind_repeat;
};
struct seat {
struct wlr_seat *seat;
struct server *server;
@ -37,10 +111,9 @@ struct seat {
bool cursor_visible;
struct wlr_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager;
struct accumulated_scroll {
double delta;
double delta_discrete;
} accumulated_scrolls[2]; /* indexed by wl_pointer_axis */
struct {
double x, y;
} smooth_scroll_offset;
bool cursor_scroll_wheel_emulation;
/*
@ -55,6 +128,9 @@ struct seat {
struct wlr_pointer_constraint_v1 *current_constraint;
/* In support for ToggleKeybinds */
uint32_t nr_inhibited_keybind_views;
/* Used to hide the workspace OSD after switching workspaces */
struct wl_event_source *workspace_osd_timer;
bool workspace_osd_shown_by_modifier;
@ -142,12 +218,21 @@ struct seat {
struct wl_listener pressed_surface_destroy;
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
struct wl_listener new_virtual_pointer;
struct wl_listener virtual_pointer_new;
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
struct wl_listener new_virtual_keyboard;
};
struct lab_data_buffer;
struct workspace;
enum lab_cycle_dir {
LAB_CYCLE_DIR_NONE,
LAB_CYCLE_DIR_FORWARD,
LAB_CYCLE_DIR_BACKWARD,
};
struct server {
struct wl_display *wl_display;
struct wl_event_loop *wl_event_loop; /* Can be used for timer events */
@ -203,7 +288,7 @@ struct server {
double grab_x, grab_y;
/* View geometry when interactive move/resize is requested */
struct wlr_box grab_box;
enum lab_edge resize_edges;
uint32_t resize_edges;
/*
* 'active_view' is generally the view with keyboard-focus, updated with
@ -219,7 +304,7 @@ struct server {
*/
struct view *active_view;
struct ssd_button *hovered_button;
struct ssd_hover_state *ssd_hover_state;
/* Tree for all non-layer xdg/xwayland-shell surfaces */
struct wlr_scene_tree *view_tree;
@ -303,7 +388,6 @@ struct server {
/* Set when in cycle (alt-tab) mode */
struct osd_state {
struct view *cycle_view;
bool preview_was_shaded;
bool preview_was_enabled;
struct wlr_scene_node *preview_node;
struct wlr_scene_tree *preview_parent;
@ -321,6 +405,45 @@ struct server {
pid_t primary_client_pid;
};
#define LAB_NR_LAYERS (4)
struct output {
struct wl_list link; /* server.outputs */
struct server *server;
struct wlr_output *wlr_output;
struct wlr_output_state pending;
struct wlr_scene_output *scene_output;
struct wlr_scene_tree *layer_tree[LAB_NR_LAYERS];
struct wlr_scene_tree *layer_popup_tree;
struct wlr_scene_tree *osd_tree;
struct wlr_scene_tree *session_lock_tree;
struct wlr_scene_buffer *workspace_osd;
struct osd_scene {
struct wl_array items; /* struct osd_scene_item */
struct wlr_scene_tree *tree;
} osd_scene;
/* In output-relative scene coordinates */
struct wlr_box usable_area;
struct wl_list regions; /* struct region.link */
struct wl_listener destroy;
struct wl_listener frame;
struct wl_listener request_state;
bool gamma_lut_changed;
};
#undef LAB_NR_LAYERS
struct constraint {
struct seat *seat;
struct wlr_pointer_constraint_v1 *constraint;
struct wl_listener destroy;
};
void xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup);
void xdg_shell_init(struct server *server);
void xdg_shell_finish(struct server *server);
@ -360,6 +483,7 @@ void desktop_focus_view_or_surface(struct seat *seat, struct view *view,
void desktop_arrange_all_views(struct server *server);
void desktop_focus_output(struct output *output);
struct view *desktop_topmost_focusable_view(struct server *server);
/**
* Toggles the (output local) visibility of the layershell top layer
@ -420,20 +544,50 @@ void seat_focus_override_end(struct seat *seat);
*/
void interactive_anchor_to_cursor(struct server *server, struct wlr_box *geo);
void interactive_begin(struct view *view, enum input_mode mode,
enum lab_edge edges);
void interactive_begin(struct view *view, enum input_mode mode, uint32_t edges);
void interactive_finish(struct view *view);
void interactive_cancel(struct view *view);
/* Possibly returns VIEW_EDGE_CENTER if <topMaximize> is yes */
enum view_edge edge_from_cursor(struct seat *seat, struct output **dest_output);
void output_init(struct server *server);
void output_finish(struct server *server);
void output_manager_init(struct server *server);
struct output *output_from_wlr_output(struct server *server,
struct wlr_output *wlr_output);
struct output *output_from_name(struct server *server, const char *name);
struct output *output_nearest_to(struct server *server, int lx, int ly);
struct output *output_nearest_to_cursor(struct server *server);
/**
* Returns the edge to snap a window to.
* For example, if the output-relative cursor position (x,y) fulfills
* x <= (<snapping><cornerRange>) and y <= (<snapping><range>),
* then edge1=LAB_EDGE_TOP and edge2=LAB_EDGE_LEFT.
* The value of (edge1|edge2) can be passed to view_snap_to_edge().
* output_get_adjacent() - get next output, in a given direction,
* from a given output
*
* @output: reference output
* @edge: direction in which to look for the nearest output
* @wrap: if true, wrap around at layout edge
*
* Note: if output is NULL, the output nearest the cursor will be used as the
* reference instead.
*/
bool edge_from_cursor(struct seat *seat, struct output **dest_output,
enum lab_edge *edge1, enum lab_edge *edge2);
struct output *output_get_adjacent(struct output *output,
enum view_edge edge, bool wrap);
bool output_is_usable(struct output *output);
void output_update_usable_area(struct output *output);
void output_update_all_usable_areas(struct server *server, bool layout_changed);
bool output_get_tearing_allowance(struct output *output);
struct wlr_box output_usable_area_in_layout_coords(struct output *output);
void handle_output_power_manager_set_mode(struct wl_listener *listener,
void *data);
void output_enable_adaptive_sync(struct output *output, bool enabled);
/**
* output_max_scale() - get maximum scale factor of all usable outputs.
* Used when loading/rendering resources (e.g. icons) that may be
* displayed on any output.
*/
float output_max_scale(struct server *server);
void handle_tearing_new_object(struct wl_listener *listener, void *data);

View file

@ -1,9 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_LAYERS_H
#define LABWC_LAYERS_H
#include <wayland-server-core.h>
#include <wlr/util/box.h>
#include <wayland-server.h>
#include <wlr/types/wlr_layer_shell_v1.h>
struct server;
struct output;

View file

@ -100,6 +100,18 @@ void menu_open_root(struct menu *menu, int x, int y);
*/
void menu_process_cursor_motion(struct wlr_scene_node *node);
/**
* menu_call_actions - call actions associated with a menu node
*
* If menuitem connected to @node does not just open a submenu:
* - associated actions will be called
* - server->menu_current will be closed
* - server->menu_current will be set to NULL
*
* Returns true if actions have actually been executed
*/
bool menu_call_actions(struct wlr_scene_node *node);
/**
* menu_close_root- close root menu
*

View file

@ -1,15 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_NODE_DESCRIPTOR_H
#define LABWC_NODE_DESCRIPTOR_H
#include <wlr/types/wlr_scene.h>
#include <wayland-server-core.h>
#include "common/node-type.h"
struct view;
struct lab_layer_surface;
struct lab_layer_popup;
struct menuitem;
struct ssd_button;
struct scaled_scene_buffer;
struct wlr_scene_node;
enum node_descriptor_type {
LAB_NODE_DESC_NODE = 0,
LAB_NODE_DESC_VIEW,
LAB_NODE_DESC_XDG_POPUP,
LAB_NODE_DESC_LAYER_SURFACE,
LAB_NODE_DESC_LAYER_POPUP,
LAB_NODE_DESC_SESSION_LOCK_SURFACE,
LAB_NODE_DESC_IME_POPUP,
LAB_NODE_DESC_MENUITEM,
LAB_NODE_DESC_TREE,
LAB_NODE_DESC_SCALED_SCENE_BUFFER,
LAB_NODE_DESC_SSD_BUTTON,
};
struct node_descriptor {
enum lab_node_type type;
struct view *view;
enum node_descriptor_type type;
void *data;
struct wl_listener destroy;
};
@ -22,15 +38,16 @@ struct node_descriptor {
*
* @scene_node: wlr_scene_node to attached node_descriptor to
* @type: node descriptor type
* @view: associated view
* @data: struct to point to as follows:
* - LAB_NODE_LAYER_SURFACE struct lab_layer_surface
* - LAB_NODE_LAYER_POPUP struct lab_layer_popup
* - LAB_NODE_MENUITEM struct menuitem
* - LAB_NODE_BUTTON_* struct ssd_button
* - LAB_NODE_DESC_VIEW struct view
* - LAB_NODE_DESC_XDG_POPUP struct view
* - LAB_NODE_DESC_LAYER_SURFACE struct lab_layer_surface
* - LAB_NODE_DESC_LAYER_POPUP struct lab_layer_popup
* - LAB_NODE_DESC_MENUITEM struct menuitem
* - LAB_NODE_DESC_SSD_BUTTON struct ssd_button
*/
void node_descriptor_create(struct wlr_scene_node *scene_node,
enum lab_node_type type, struct view *view, void *data);
enum node_descriptor_type type, void *data);
/**
* node_view_from_node - return view struct from node
@ -45,6 +62,13 @@ struct view *node_view_from_node(struct wlr_scene_node *wlr_scene_node);
struct lab_layer_surface *node_layer_surface_from_node(
struct wlr_scene_node *wlr_scene_node);
/**
* node_layer_popup_from_node - return lab_layer_popup struct from node
* @wlr_scene_node: wlr_scene_node from which to return data
*/
struct lab_layer_popup *node_layer_popup_from_node(
struct wlr_scene_node *wlr_scene_node);
/**
* node_menuitem_from_node - return menuitem struct from node
* @wlr_scene_node: wlr_scene_node from which to return data
@ -53,10 +77,17 @@ struct menuitem *node_menuitem_from_node(
struct wlr_scene_node *wlr_scene_node);
/**
* node_try_ssd_button_from_node - return ssd_button or NULL from node
* node_ssd_button_from_node - return ssd_button struct from node
* @wlr_scene_node: wlr_scene_node from which to return data
*/
struct ssd_button *node_try_ssd_button_from_node(
struct ssd_button *node_ssd_button_from_node(
struct wlr_scene_node *wlr_scene_node);
/**
* node_scaled_scene_buffer_from_node - return scaled_scene_buffer from node
* @wlr_scene_node: wlr_scene_node from which to return data
*/
struct scaled_scene_buffer *node_scaled_scene_buffer_from_node(
struct wlr_scene_node *wlr_scene_node);
#endif /* LABWC_NODE_DESCRIPTOR_H */

View file

@ -5,14 +5,6 @@
#include <stdbool.h>
#include <wayland-server-core.h>
struct output;
enum lab_cycle_dir {
LAB_CYCLE_DIR_NONE,
LAB_CYCLE_DIR_FORWARD,
LAB_CYCLE_DIR_BACKWARD,
};
/* TODO: add field with keyboard layout? */
enum window_switcher_field_content {
LAB_FIELD_NONE = 0,
@ -45,6 +37,7 @@ struct window_switcher_field {
struct buf;
struct view;
struct server;
enum lab_cycle_dir;
/* Begin window switcher */
void osd_begin(struct server *server, enum lab_cycle_dir direction);
@ -63,26 +56,10 @@ void osd_field_get_content(struct window_switcher_field *field,
struct buf *buf, struct view *view);
/* Used by rcxml.c when parsing the config */
struct window_switcher_field *osd_field_create(void);
void osd_field_arg_from_xml_node(struct window_switcher_field *field,
const char *nodename, const char *content);
bool osd_field_is_valid(struct window_switcher_field *field);
void osd_field_free(struct window_switcher_field *field);
/* Internal API */
struct osd_impl {
/*
* Create a scene-tree of OSD for an output.
* This sets output->osd_scene.{items,tree}.
*/
void (*create)(struct output *output, struct wl_array *views);
/*
* Update output->osd_scene.tree to highlight
* server->osd_state.cycle_view.
*/
void (*update)(struct output *output);
};
extern struct osd_impl osd_classic_impl;
extern struct osd_impl osd_thumbnail_impl;
#endif // LABWC_OSD_H

View file

@ -1,72 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_OUTPUT_H
#define LABWC_OUTPUT_H
#include <wlr/types/wlr_output.h>
#include "common/edge.h"
#define LAB_NR_LAYERS (4)
struct output {
struct wl_list link; /* server.outputs */
struct server *server;
struct wlr_output *wlr_output;
struct wlr_output_state pending;
struct wlr_scene_output *scene_output;
struct wlr_scene_tree *layer_tree[LAB_NR_LAYERS];
struct wlr_scene_tree *layer_popup_tree;
struct wlr_scene_tree *osd_tree;
struct wlr_scene_tree *session_lock_tree;
struct wlr_scene_buffer *workspace_osd;
struct osd_scene {
struct wl_array items; /* struct osd_scene_item */
struct wlr_scene_tree *tree;
} osd_scene;
/* In output-relative scene coordinates */
struct wlr_box usable_area;
struct wl_list regions; /* struct region.link */
struct wl_listener destroy;
struct wl_listener frame;
struct wl_listener request_state;
bool gamma_lut_changed;
};
#undef LAB_NR_LAYERS
void output_init(struct server *server);
void output_finish(struct server *server);
struct output *output_from_wlr_output(struct server *server,
struct wlr_output *wlr_output);
struct output *output_from_name(struct server *server, const char *name);
struct output *output_nearest_to(struct server *server, int lx, int ly);
struct output *output_nearest_to_cursor(struct server *server);
/**
* output_get_adjacent() - get next output, in a given direction,
* from a given output
*
* @output: reference output
* @edge: direction in which to look for the nearest output
* @wrap: if true, wrap around at layout edge
*
* Note: if output is NULL, the output nearest the cursor will be used as the
* reference instead.
*/
struct output *output_get_adjacent(struct output *output,
enum lab_edge edge, bool wrap);
bool output_is_usable(struct output *output);
void output_update_usable_area(struct output *output);
void output_update_all_usable_areas(struct server *server, bool layout_changed);
bool output_get_tearing_allowance(struct output *output);
struct wlr_box output_usable_area_in_layout_coords(struct output *output);
void handle_output_power_manager_set_mode(struct wl_listener *listener,
void *data);
void output_enable_adaptive_sync(struct output *output, bool enabled);
#endif // LABWC_OUTPUT_H

View file

@ -2,12 +2,24 @@
#ifndef LABWC_OVERLAY_H
#define LABWC_OVERLAY_H
#include "common/edge.h"
#include <wlr/util/box.h>
#include "common/graphic-helpers.h"
#include "regions.h"
#include "view.h"
struct seat;
/* TODO: replace this with single lab_scene_rect */
struct overlay_rect {
struct wlr_scene_tree *tree;
bool bg_enabled;
struct wlr_scene_rect *bg_rect;
bool border_enabled;
struct lab_scene_rect *border_rect;
};
struct overlay {
struct lab_scene_rect *rect;
struct overlay_rect region_rect, edge_rect;
/* Represents currently shown or delayed overlay */
struct {
@ -15,7 +27,7 @@ struct overlay {
struct region *region;
/* Snap-to-edge overlay */
enum lab_edge edge;
enum view_edge edge;
struct output *output;
} active;
@ -23,13 +35,15 @@ struct overlay {
struct wl_event_source *timer;
};
/*
* Shows or updates an overlay when the grabbed window can be snapped to
* a region or an output edge. Calls overlay_finish() otherwise.
*/
void overlay_reconfigure(struct seat *seat);
/* Calls overlay_hide() internally if there's no overlay to show */
void overlay_update(struct seat *seat);
/* Destroys the overlay if it exists */
/* This function must be called when server->grabbed_view is destroyed */
void overlay_hide(struct seat *seat);
/* This function is called to clean up the timer on exit */
void overlay_finish(struct seat *seat);
#endif

View file

@ -4,8 +4,7 @@
#include <stdbool.h>
#include <wlr/util/box.h>
struct view;
#include "view.h"
bool placement_find_best(struct view *view, struct wlr_box *geometry);

View file

@ -1,11 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_RESISTANCE_H
#define LABWC_RESISTANCE_H
#include <stdbool.h>
#include <wlr/util/box.h>
struct view;
#include "labwc.h"
/**
* resistance_unsnap_apply() - Apply resistance when dragging a

View file

@ -5,6 +5,12 @@
struct server;
struct view;
enum resize_indicator_mode {
LAB_RESIZE_INDICATOR_NEVER = 0,
LAB_RESIZE_INDICATOR_ALWAYS,
LAB_RESIZE_INDICATOR_NON_PIXEL
};
void resize_indicator_reconfigure(struct server *server);
void resize_indicator_show(struct view *view);
void resize_indicator_update(struct view *view);

View file

@ -2,7 +2,7 @@
#ifndef LABWC_SESSION_LOCK_H
#define LABWC_SESSION_LOCK_H
#include <wayland-server-core.h>
#include <wlr/types/wlr_session_lock_v1.h>
struct output;
struct server;

View file

@ -2,19 +2,21 @@
#ifndef LABWC_SNAP_CONSTRAINTS_H
#define LABWC_SNAP_CONSTRAINTS_H
#include "common/edge.h"
#include <wlr/util/edges.h>
#include "common/border.h"
#include "view.h"
struct view;
struct wlr_box;
void snap_constraints_set(struct view *view, enum lab_edge direction,
struct wlr_box geom);
void snap_constraints_set(struct view *view,
enum wlr_edges direction, struct wlr_box geom);
void snap_constraints_invalidate(struct view *view);
void snap_constraints_update(struct view *view);
struct wlr_box snap_constraints_effective(struct view *view,
enum lab_edge direction, bool use_pending);
enum wlr_edges direction, bool use_pending);
#endif /* LABWC_SNAP_CONSTRAINTS_H */

View file

@ -2,19 +2,19 @@
#ifndef LABWC_SNAP_H
#define LABWC_SNAP_H
#include "common/edge.h"
#include "common/border.h"
#include "view.h"
struct view;
struct wlr_box;
void snap_move_to_edge(struct view *view,
enum lab_edge direction, bool snap_to_windows, int *dx, int *dy);
enum view_edge direction, bool snap_to_windows, int *dx, int *dy);
void snap_grow_to_next_edge(struct view *view,
enum lab_edge direction, struct wlr_box *geo);
enum view_edge direction, struct wlr_box *geo);
void snap_shrink_to_next_edge(struct view *view,
enum lab_edge direction, struct wlr_box *geo);
enum view_edge direction, struct wlr_box *geo);
void snap_invalidate_edge_cache(struct view *view);
void snap_update_cache_geometry(struct view *view);

View file

@ -3,54 +3,51 @@
#define LABWC_SSD_INTERNAL_H
#include <wlr/util/box.h>
#include "common/border.h"
#include "theme.h"
#include "common/macros.h"
#include "ssd.h"
#include "view.h"
#define FOR_EACH(tmp, ...) \
{ \
__typeof__(tmp) _x[] = { __VA_ARGS__, NULL }; \
size_t _i = 0; \
for ((tmp) = _x[_i]; _i < ARRAY_SIZE(_x) - 1; (tmp) = _x[++_i])
#define FOR_EACH_END }
struct ssd_button {
struct view *view;
enum ssd_part_type type;
/*
* Bitmap of lab_button_state that represents a combination of
* hover/toggled/rounded states.
*/
uint8_t state_set;
/*
* Image buffers for each combination of hover/toggled/rounded states.
* img_buffers[state_set] is displayed. Some of these can be NULL
* (e.g. img_buffers[LAB_BS_ROUNDED] is set only for corner buttons).
*
* When "type" is LAB_SSD_BUTTON_WINDOW_ICON, these are all NULL and
* window_icon is used instead.
*/
struct scaled_img_buffer *img_buffers[LAB_BS_ALL + 1];
struct scaled_icon_buffer *window_icon;
struct wl_listener destroy;
};
struct ssd_sub_tree {
struct wlr_scene_tree *tree;
struct wl_list parts; /* ssd_part.link */
};
struct ssd_state_title_width {
int width;
bool truncated;
};
/*
* The scene-graph of SSD looks like below. The parentheses indicate the
* type of each node (enum lab_node_type, stored in the node_descriptor
* attached to the wlr_scene_node).
*
* ssd->tree (LAB_NODE_SSD_ROOT)
* +--titlebar (LAB_NODE_TITLEBAR)
* | +--inactive
* | | +--background bar
* | | +--left corner
* | | +--right corner
* | | +--title (LAB_NODE_TITLE)
* | | +--iconify button (LAB_NODE_BUTTON_ICONIFY)
* | | | +--normal close icon image
* | | | +--hovered close icon image
* | | | +--...
* | | +--window icon (LAB_NODE_BUTTON_WINDOW_ICON)
* | | | +--window icon image
* | | +--...
* | +--active
* | +--...
* +--border
* | +--inactive
* | | +--top
* | | +--...
* | +--active
* | +--top
* | +--...
* +--shadow
* | +--inactive
* | | +--top
* | | +--...
* | +--active
* | +--top
* | +--...
* +--extents
* +--top
* +--...
*/
struct ssd {
struct view *view;
struct wlr_scene_tree *tree;
@ -83,48 +80,33 @@ struct ssd {
struct wlr_box geometry;
struct ssd_state_title {
char *text;
/* indexed by enum ssd_active_state */
struct ssd_state_title_width dstates[2];
struct ssd_state_title_width active;
struct ssd_state_title_width inactive;
} title;
} state;
/* An invisible area around the view which allows resizing */
struct ssd_extents_scene {
struct wlr_scene_tree *tree;
struct wlr_scene_rect *top, *bottom, *left, *right;
} extents;
struct ssd_sub_tree extents;
/* The top of the view, containing buttons, title, .. */
struct ssd_titlebar_scene {
struct {
int height;
struct wlr_scene_tree *tree;
struct ssd_titlebar_subtree {
struct wlr_scene_tree *tree;
struct wlr_scene_buffer *corner_left;
struct wlr_scene_buffer *corner_right;
struct wlr_scene_buffer *bar;
struct scaled_font_buffer *title;
struct wl_list buttons_left; /* ssd_button.link */
struct wl_list buttons_right; /* ssd_button.link */
} subtrees[2]; /* indexed by enum ssd_active_state */
struct ssd_sub_tree active;
struct ssd_sub_tree inactive;
} titlebar;
/* Borders allow resizing as well */
struct ssd_border_scene {
struct {
struct wlr_scene_tree *tree;
struct ssd_border_subtree {
struct wlr_scene_tree *tree;
struct wlr_scene_rect *top, *bottom, *left, *right;
} subtrees[2]; /* indexed by enum ssd_active_state */
struct ssd_sub_tree active;
struct ssd_sub_tree inactive;
} border;
struct ssd_shadow_scene {
struct {
struct wlr_scene_tree *tree;
struct ssd_shadow_subtree {
struct wlr_scene_tree *tree;
struct wlr_scene_buffer *top, *bottom, *left, *right,
*top_left, *top_right, *bottom_left, *bottom_right;
} subtrees[2]; /* indexed by enum ssd_active_state */
struct ssd_sub_tree active;
struct ssd_sub_tree inactive;
} shadow;
/*
@ -135,39 +117,47 @@ struct ssd {
struct border margin;
};
struct ssd_button {
struct ssd_part {
enum ssd_part_type type;
/* Buffer pointer. May be NULL */
struct scaled_font_buffer *buffer;
/* This part represented in scene graph */
struct wlr_scene_node *node;
enum lab_node_type type;
/*
* Bitmap of lab_button_state that represents a combination of
* hover/toggled/rounded states.
*/
uint8_t state_set;
/*
* Image buffers for each combination of hover/toggled/rounded states.
* img_buffers[state_set] is displayed. Some of these can be NULL
* (e.g. img_buffers[LAB_BS_ROUNDED] is set only for corner buttons).
*
* When the button type is LAB_NODE_BUTTON_WINDOW_ICON,
* these are all NULL and window_icon is used instead.
*/
struct scaled_img_buffer *img_buffers[LAB_BS_ALL + 1];
struct wl_list link;
};
struct scaled_icon_buffer *window_icon;
struct wl_list link; /* ssd_titlebar_subtree.buttons_{left,right} */
struct ssd_hover_state {
struct view *view;
struct ssd_button *button;
};
struct wlr_buffer;
struct wlr_scene_tree;
/* SSD internal helpers to create various SSD elements */
struct ssd_button *attach_ssd_button(struct wl_list *button_parts,
enum lab_node_type type, struct wlr_scene_tree *parent,
struct lab_img *imgs[LAB_BS_ALL + 1], int x, int y,
/* TODO: Replace some common args with a struct */
struct ssd_part *add_scene_part(
struct wl_list *part_list, enum ssd_part_type type);
struct ssd_part *add_scene_rect(
struct wl_list *list, enum ssd_part_type type,
struct wlr_scene_tree *parent, int width, int height, int x, int y,
float color[4]);
struct ssd_part *add_scene_buffer(
struct wl_list *list, enum ssd_part_type type,
struct wlr_scene_tree *parent, struct wlr_buffer *buffer, int x, int y);
struct ssd_part *add_scene_button(struct wl_list *part_list,
enum ssd_part_type type, struct wlr_scene_tree *parent,
struct lab_img *buffers[LAB_BS_ALL + 1], int x, int y,
struct view *view);
/* SSD internal helpers */
struct ssd_part *ssd_get_part(
struct wl_list *part_list, enum ssd_part_type type);
void ssd_destroy_parts(struct wl_list *list);
/* SSD internal */
void ssd_titlebar_create(struct ssd *ssd);
void ssd_titlebar_update(struct ssd *ssd);

View file

@ -2,15 +2,8 @@
#ifndef LABWC_SSD_H
#define LABWC_SSD_H
#include "common/node-type.h"
#include "config/types.h"
enum ssd_active_state {
SSD_INACTIVE = 0,
SSD_ACTIVE = 1,
};
#define FOR_EACH_ACTIVE_STATE(active) for (active = SSD_INACTIVE; active <= SSD_ACTIVE; active++)
#include <wayland-server-core.h>
#include "common/border.h"
struct wlr_cursor;
@ -21,10 +14,64 @@ struct wlr_cursor;
*/
#define SSD_SHADOW_INSET 0.3
/*
* Sequence these according to the order they should be processed for
* press and hover events. Bear in mind that some of their respective
* interactive areas overlap, so for example buttons need to come before title.
*/
enum ssd_part_type {
LAB_SSD_NONE = 0,
LAB_SSD_BUTTON_CLOSE = 1,
LAB_SSD_BUTTON_MAXIMIZE,
LAB_SSD_BUTTON_ICONIFY,
LAB_SSD_BUTTON_WINDOW_ICON,
LAB_SSD_BUTTON_WINDOW_MENU,
LAB_SSD_BUTTON_SHADE,
LAB_SSD_BUTTON_OMNIPRESENT,
/* only for internal use */
LAB_SSD_BUTTON_FIRST = LAB_SSD_BUTTON_CLOSE,
LAB_SSD_BUTTON_LAST = LAB_SSD_BUTTON_OMNIPRESENT,
LAB_SSD_BUTTON,
LAB_SSD_PART_TITLEBAR,
LAB_SSD_PART_TITLEBAR_CORNER_RIGHT,
LAB_SSD_PART_TITLEBAR_CORNER_LEFT,
LAB_SSD_PART_TITLE,
/* shared by shadows, borders and extents */
LAB_SSD_PART_CORNER_TOP_LEFT,
LAB_SSD_PART_CORNER_TOP_RIGHT,
LAB_SSD_PART_CORNER_BOTTOM_RIGHT,
LAB_SSD_PART_CORNER_BOTTOM_LEFT,
LAB_SSD_PART_TOP,
LAB_SSD_PART_RIGHT,
LAB_SSD_PART_BOTTOM,
LAB_SSD_PART_LEFT,
LAB_SSD_CLIENT,
LAB_SSD_FRAME,
LAB_SSD_ROOT,
LAB_SSD_MENU,
LAB_SSD_OSD,
LAB_SSD_LAYER_SURFACE,
LAB_SSD_LAYER_SUBSURFACE,
LAB_SSD_UNMANAGED,
LAB_SSD_ALL,
LAB_SSD_END_MARKER
};
enum ssd_mode {
LAB_SSD_MODE_INVALID,
LAB_SSD_MODE_NONE,
LAB_SSD_MODE_BORDER,
LAB_SSD_MODE_FULL,
};
/* Forward declare arguments */
struct server;
struct ssd;
struct ssd_button;
struct ssd_hover_state;
struct view;
struct wlr_scene;
struct wlr_scene_node;
@ -51,20 +98,19 @@ void ssd_set_titlebar(struct ssd *ssd, bool enabled);
void ssd_enable_keybind_inhibit_indicator(struct ssd *ssd, bool enable);
void ssd_enable_shade(struct ssd *ssd, bool enable);
void ssd_update_hovered_button(struct server *server,
struct wlr_scene_node *node);
struct ssd_hover_state *ssd_hover_state_new(void);
void ssd_update_button_hover(struct wlr_scene_node *node,
struct ssd_hover_state *hover_state);
void ssd_button_free(struct ssd_button *button);
enum ssd_part_type ssd_button_get_type(const struct ssd_button *button);
struct view *ssd_button_get_view(const struct ssd_button *button);
/* Public SSD helpers */
/*
* Returns a part type that represents a mouse context like "Top", "Left" and
* "TRCorner" when the cursor is on the window border or resizing handle.
*/
enum lab_node_type ssd_get_resizing_type(const struct ssd *ssd,
struct wlr_cursor *cursor);
enum lab_ssd_mode ssd_mode_parse(const char *mode);
enum ssd_part_type ssd_get_part_type(const struct ssd *ssd,
struct wlr_scene_node *node, struct wlr_cursor *cursor);
uint32_t ssd_resize_edges(enum ssd_part_type type);
bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate);
enum ssd_mode ssd_mode_parse(const char *mode);
/* TODO: clean up / update */
struct border ssd_thickness(struct view *view);

View file

@ -9,8 +9,8 @@
#define LABWC_THEME_H
#include <cairo.h>
#include <stdbool.h>
#include "common/node-type.h"
#include <wlr/render/wlr_renderer.h>
#include "ssd.h"
struct lab_img;
@ -41,11 +41,11 @@ struct theme_snapping_overlay {
enum lab_button_state {
LAB_BS_DEFAULT = 0,
LAB_BS_HOVERED = 1 << 0,
LAB_BS_HOVERD = 1 << 0,
LAB_BS_TOGGLED = 1 << 1,
LAB_BS_ROUNDED = 1 << 2,
LAB_BS_ALL = LAB_BS_HOVERED | LAB_BS_TOGGLED | LAB_BS_ROUNDED,
LAB_BS_ALL = LAB_BS_HOVERD | LAB_BS_TOGGLED | LAB_BS_ROUNDED,
};
struct theme_background {
@ -83,14 +83,14 @@ struct theme {
/*
* Themes/textures for each active/inactive window. Indexed by
* ssd_active_state.
* THEME_INACTIVE and THEME_ACTIVE.
*/
struct {
/* title background pattern (solid or gradient) */
struct theme_background title_bg;
/* TODO: add toggled/hover/pressed/disabled colors for buttons */
float button_colors[LAB_NODE_BUTTON_LAST + 1][4];
float button_colors[LAB_SSD_BUTTON_LAST + 1][4];
float border_color[4];
float toggled_keybinds_color[4];
@ -104,12 +104,12 @@ struct theme {
* The texture of a window buttons for each hover/toggled/rounded
* state. This can be accessed like:
*
* buttons[LAB_NODE_BUTTON_ICONIFY][LAB_BS_HOVERED | LAB_BS_TOGGLED]
* buttons[LAB_SSD_BUTTON_ICONIFY][LAB_BS_HOVERD | LAB_BS_TOGGLED]
*
* Elements in buttons[0] are all NULL since LAB_NODE_BUTTON_FIRST is 1.
* Elements in buttons[0] are all NULL since LAB_SSD_BUTTON_FIRST is 1.
*/
struct lab_img *button_imgs
[LAB_NODE_BUTTON_LAST + 1][LAB_BS_ALL + 1];
[LAB_SSD_BUTTON_LAST + 1][LAB_BS_ALL + 1];
/*
* The titlebar background is specified as a cairo_pattern
@ -164,39 +164,13 @@ struct theme {
float osd_border_color[4];
float osd_label_text_color[4];
struct window_switcher_classic_theme {
int width;
int padding;
int item_padding_x;
int item_padding_y;
int item_active_border_width;
float item_active_border_color[4];
float item_active_bg_color[4];
int item_icon_size;
bool width_is_percent;
/*
* Not set in rc.xml/themerc, but derived from the tallest
* titlebar object plus 2 * window_titlebar_padding_height
*/
int item_height;
} osd_window_switcher_classic;
struct window_switcher_thumbnail_theme {
int max_width;
int padding;
int item_width;
int item_height;
int item_padding;
int item_active_border_width;
float item_active_border_color[4];
float item_active_bg_color[4];
int item_icon_size;
bool max_width_is_percent;
int title_height;
} osd_window_switcher_thumbnail;
int osd_window_switcher_width;
int osd_window_switcher_padding;
int osd_window_switcher_item_padding_x;
int osd_window_switcher_item_padding_y;
int osd_window_switcher_item_active_border_width;
int osd_window_switcher_item_icon_size;
bool osd_window_switcher_width_is_percent;
int osd_window_switcher_preview_border_width;
float osd_window_switcher_preview_border_color[3][4];
@ -207,11 +181,20 @@ struct theme {
struct theme_snapping_overlay
snapping_overlay_region, snapping_overlay_edge;
/*
* Not set in rc.xml/themerc, but derived from the tallest titlebar
* object plus 2 * window_titlebar_padding_height
*/
int osd_window_switcher_item_height;
/* magnifier */
float mag_border_color[4];
int mag_border_width;
};
#define THEME_INACTIVE 0
#define THEME_ACTIVE 1
struct server;
/**

View file

@ -1,14 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef LABWC_TRANSLATE_H
#define LABWC_TRANSLATE_H
#include "config.h"
#if HAVE_NLS
#include <libintl.h>
#include <locale.h>
#define _ gettext
#else
#define _(s) (s)
#endif
#endif /* LABWC_TRANSLATE_H */

View file

@ -2,20 +2,16 @@
#ifndef LABWC_VIEW_H
#define LABWC_VIEW_H
#include "config/rcxml.h"
#include "config.h"
#include "ssd.h"
#include <stdbool.h>
#include <stdint.h>
#include <wayland-util.h>
#include <wlr/util/box.h>
#include <xkbcommon/xkbcommon.h>
#include "common/edge.h"
#include "config.h"
#include "config/types.h"
#include "common/three-state.h"
/*
* Default minimal window size. Clients can explicitly set smaller values via
* e.g. xdg_toplevel::set_min_size.
*/
#define LAB_MIN_VIEW_WIDTH 100
#define LAB_MIN_VIEW_HEIGHT 60
/*
@ -32,6 +28,7 @@
* In labwc, a view is a container for surfaces which can be moved around by
* the user. In practice this means XDG toplevel and XWayland windows.
*/
enum view_type {
LAB_XDG_SHELL_VIEW,
#if HAVE_XWAYLAND
@ -62,6 +59,16 @@ enum view_axis {
VIEW_AXIS_INVALID = (1 << 2),
};
enum view_edge {
VIEW_EDGE_INVALID = 0,
VIEW_EDGE_LEFT,
VIEW_EDGE_RIGHT,
VIEW_EDGE_UP,
VIEW_EDGE_DOWN,
VIEW_EDGE_CENTER,
};
enum view_wants_focus {
/* View does not want focus */
VIEW_WANTS_FOCUS_NEVER = 0,
@ -82,6 +89,33 @@ enum view_wants_focus {
VIEW_WANTS_FOCUS_UNLIKELY,
};
/*
* Window types are based on the NET_WM constants from X11. See:
* https://specifications.freedesktop.org/wm-spec/1.4/ar01s05.html#id-1.6.7
*
* The enum constants are intended to match wlr_xwayland_net_wm_window_type.
* Redefining the same constants here may seem redundant, but is necessary
* to make them available even in builds with xwayland support disabled.
*/
enum window_type {
NET_WM_WINDOW_TYPE_DESKTOP = 0,
NET_WM_WINDOW_TYPE_DOCK,
NET_WM_WINDOW_TYPE_TOOLBAR,
NET_WM_WINDOW_TYPE_MENU,
NET_WM_WINDOW_TYPE_UTILITY,
NET_WM_WINDOW_TYPE_SPLASH,
NET_WM_WINDOW_TYPE_DIALOG,
NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
NET_WM_WINDOW_TYPE_POPUP_MENU,
NET_WM_WINDOW_TYPE_TOOLTIP,
NET_WM_WINDOW_TYPE_NOTIFICATION,
NET_WM_WINDOW_TYPE_COMBO,
NET_WM_WINDOW_TYPE_DND,
NET_WM_WINDOW_TYPE_NORMAL,
WINDOW_TYPE_LEN
};
struct view;
struct wlr_surface;
struct foreign_toplevel;
@ -106,6 +140,7 @@ struct view_size_hints {
struct view_impl {
void (*configure)(struct view *view, struct wlr_box geo);
void (*close)(struct view *view);
const char *(*get_string_prop)(struct view *view, const char *prop);
void (*map)(struct view *view);
void (*set_activated)(struct view *view, bool activated);
void (*set_fullscreen)(struct view *view, bool fullscreen);
@ -130,7 +165,7 @@ struct view_impl {
bool (*has_strut_partial)(struct view *self);
/* returns true if view declared itself a window type */
bool (*contains_window_type)(struct view *view,
enum lab_window_type window_type);
enum window_type window_type);
/* returns the client pid that this view belongs to */
pid_t (*get_pid)(struct view *view);
};
@ -172,24 +207,21 @@ struct view {
struct wlr_scene_tree *scene_tree;
struct wlr_scene_tree *content_tree;
/* These are never NULL and an empty string is set instead. */
char *title;
char *app_id; /* WM_CLASS for xwayland windows */
bool mapped;
bool been_mapped;
enum lab_ssd_mode ssd_mode;
bool ssd_enabled;
bool ssd_titlebar_hidden;
enum ssd_preference ssd_preference;
bool shaded;
bool minimized;
enum view_axis maximized;
bool fullscreen;
bool tearing_hint;
enum lab_tristate force_tearing;
enum three_state force_tearing;
bool visible_on_all_workspaces;
enum lab_edge tiled;
enum lab_edge edges_visible;
bool inhibits_keybinds; /* also inhibits mousebinds */
enum view_edge tiled;
uint32_t edges_visible; /* enum wlr_edges bitset */
bool inhibits_keybinds;
xkb_layout_index_t keyboard_layout;
/* Pointer to an output owned struct region, may be NULL */
@ -282,18 +314,18 @@ struct view_query {
struct wl_list link;
char *identifier;
char *title;
enum lab_window_type window_type;
int window_type;
char *sandbox_engine;
char *sandbox_app_id;
enum lab_tristate shaded;
enum three_state shaded;
enum view_axis maximized;
enum lab_tristate iconified;
enum lab_tristate focused;
enum lab_tristate omnipresent;
enum lab_edge tiled;
enum three_state iconified;
enum three_state focused;
enum three_state omnipresent;
enum view_edge tiled;
char *tiled_region;
char *desktop;
enum lab_ssd_mode decoration;
enum ssd_mode decoration;
char *monitor;
};
@ -307,6 +339,28 @@ struct xdg_toplevel_view {
struct wl_listener new_popup;
};
/* All criteria is applied in AND logic */
enum lab_view_criteria {
/* No filter -> all focusable views */
LAB_VIEW_CRITERIA_NONE = 0,
/*
* Includes always-on-top views, e.g.
* what is visible on the current workspace
*/
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
/* Positive criteria */
LAB_VIEW_CRITERIA_FULLSCREEN = 1 << 1,
LAB_VIEW_CRITERIA_ALWAYS_ON_TOP = 1 << 2,
LAB_VIEW_CRITERIA_ROOT_TOPLEVEL = 1 << 3,
/* Negative criteria */
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 6,
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 7,
LAB_VIEW_CRITERIA_NO_OMNIPRESENT = 1 << 8,
};
/**
* view_from_wlr_surface() - returns the view associated with a
* wlr_surface, or NULL if the surface has no associated view.
@ -428,11 +482,16 @@ void view_array_append(struct server *server, struct wl_array *views,
enum lab_view_criteria criteria);
enum view_wants_focus view_wants_focus(struct view *view);
bool view_contains_window_type(struct view *view, enum window_type window_type);
/* If view is NULL, the size of SSD is not considered */
struct wlr_box view_get_edge_snap_box(struct view *view, struct output *output,
enum lab_edge edge);
struct wlr_box view_get_region_snap_box(struct view *view, struct region *region);
/**
* view_edge_invert() - select the opposite of a provided edge
*
* VIEW_EDGE_CENTER and VIEW_EDGE_INVALID both map to VIEW_EDGE_INVALID.
*
* @edge: edge to be inverted
*/
enum view_edge view_edge_invert(enum view_edge edge);
/**
* view_is_focusable() - Check whether or not a view can be focused
@ -454,15 +513,11 @@ bool view_is_focusable(struct view *view);
*/
void view_offer_focus(struct view *view);
struct wlr_box view_get_edge_snap_box(struct view *view, struct output *output,
enum lab_edge edge);
void mappable_connect(struct mappable *mappable, struct wlr_surface *surface,
wl_notify_func_t notify_map, wl_notify_func_t notify_unmap);
void mappable_disconnect(struct mappable *mappable);
void view_toggle_keybinds(struct view *view);
bool view_inhibits_actions(struct view *view, struct wl_list *actions);
void view_set_activated(struct view *view, bool activated);
void view_set_output(struct view *view, struct output *output);
@ -486,7 +541,7 @@ void view_moved(struct view *view);
void view_minimize(struct view *view, bool minimized);
bool view_compute_centered_position(struct view *view,
const struct wlr_box *ref, int w, int h, int *x, int *y);
struct wlr_box view_get_fallback_natural_geometry(struct view *view);
void view_set_fallback_natural_geometry(struct view *view);
void view_store_natural_geometry(struct view *view);
/**
@ -517,10 +572,10 @@ void view_center(struct view *view, const struct wlr_box *ref);
* @policy: placement policy to apply
*/
void view_place_by_policy(struct view *view, bool allow_cursor,
enum lab_placement_policy policy);
enum view_placement_policy policy);
void view_constrain_size_to_that_of_usable_area(struct view *view);
void view_set_maximized(struct view *view, enum view_axis maximized);
void view_restore_to(struct view *view, struct wlr_box geometry);
void view_set_untiled(struct view *view);
void view_maximize(struct view *view, enum view_axis axis,
bool store_natural_geometry);
@ -540,22 +595,24 @@ bool view_is_tiled(struct view *view);
bool view_is_tiled_and_notify_tiled(struct view *view);
bool view_is_floating(struct view *view);
void view_move_to_workspace(struct view *view, struct workspace *workspace);
bool view_titlebar_visible(struct view *view);
void view_set_ssd_mode(struct view *view, enum lab_ssd_mode mode);
void view_set_decorations(struct view *view, enum lab_ssd_mode mode, bool force_ssd);
enum ssd_mode view_get_ssd_mode(struct view *view);
void view_set_ssd_mode(struct view *view, enum ssd_mode mode);
void view_set_decorations(struct view *view, enum ssd_mode mode, bool force_ssd);
void view_toggle_fullscreen(struct view *view);
void view_invalidate_last_layout_geometry(struct view *view);
void view_adjust_for_layout_change(struct view *view);
void view_move_to_edge(struct view *view, enum lab_edge direction, bool snap_to_windows);
void view_grow_to_edge(struct view *view, enum lab_edge direction);
void view_shrink_to_edge(struct view *view, enum lab_edge direction);
void view_snap_to_edge(struct view *view, enum lab_edge direction,
bool across_outputs, bool combine, bool store_natural_geometry);
void view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_windows);
void view_grow_to_edge(struct view *view, enum view_edge direction);
void view_shrink_to_edge(struct view *view, enum view_edge direction);
void view_snap_to_edge(struct view *view, enum view_edge direction,
bool across_outputs, bool store_natural_geometry);
void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry);
void view_move_to_output(struct view *view, struct output *output);
void view_move_to_front(struct view *view);
void view_move_to_back(struct view *view);
struct view *view_get_root(struct view *view);
void view_append_children(struct view *view, struct wl_array *children);
/**
* view_get_modal_dialog() - returns any modal dialog found among this
@ -574,9 +631,11 @@ bool view_on_output(struct view *view, struct output *output);
*/
bool view_has_strut_partial(struct view *view);
void view_set_title(struct view *view, const char *title);
void view_set_app_id(struct view *view, const char *app_id);
const char *view_get_string_prop(struct view *view, const char *prop);
void view_update_title(struct view *view);
void view_update_app_id(struct view *view);
void view_reload_ssd(struct view *view);
int view_get_min_width(void);
void view_set_shade(struct view *view, bool shaded);
@ -595,7 +654,8 @@ void view_init(struct view *view);
void view_destroy(struct view *view);
enum view_axis view_axis_parse(const char *direction);
enum lab_placement_policy view_placement_parse(const char *policy);
enum view_edge view_edge_parse(const char *direction);
enum view_placement_policy view_placement_parse(const char *policy);
/* xdg.c */
struct wlr_xdg_surface *xdg_surface_from_view(struct view *view);

View file

@ -4,7 +4,6 @@
#include <stdbool.h>
#include <wayland-util.h>
#include "config/types.h"
enum window_rule_event {
LAB_WINDOW_RULE_EVENT_ON_FIRST_MAP = 0,
@ -25,7 +24,7 @@ enum property {
struct window_rule {
char *identifier;
char *title;
enum lab_window_type window_type;
int window_type;
char *sandbox_engine;
char *sandbox_app_id;
bool match_once;

View file

@ -65,6 +65,8 @@ void xwayland_unmanaged_create(struct server *server,
void xwayland_view_create(struct server *server,
struct wlr_xwayland_surface *xsurface, bool mapped);
struct wlr_xwayland_surface *xwayland_surface_from_view(struct view *view);
void xwayland_server_init(struct server *server,
struct wlr_compositor *compositor);
void xwayland_server_finish(struct server *server);

View file

@ -1,7 +1,7 @@
project(
'labwc',
'c',
version: '0.9.2',
version: '0.9.1',
license: 'GPL-2.0-only',
meson_version: '>=0.59.0',
default_options: [
@ -127,24 +127,13 @@ conf_data.set10('HAVE_RSVG', have_rsvg)
conf_data.set10('HAVE_LIBSFDO', have_libsfdo)
foreach sym : ['LIBINPUT_CONFIG_DRAG_LOCK_ENABLED_STICKY', 'LIBINPUT_CONFIG_3FG_DRAG_ENABLED_3FG']
has_sym = input.type_name() != 'internal' \
and cc.has_header_symbol('libinput.h', sym, dependencies: input)
conf_data.set10('HAVE_' + sym, has_sym)
conf_data.set10('HAVE_' + sym, cc.has_header_symbol('libinput.h', sym, dependencies: input))
endforeach
if get_option('static_analyzer').enabled()
add_project_arguments(['-fanalyzer'], language: 'c')
endif
link_args = []
if get_option('sections').enabled()
add_project_arguments(['-ffunction-sections'], language: 'c')
link_args += [
'-Wl,--gc-sections',
'-Wl,--print-gc-sections',
]
endif
msgfmt = find_program('msgfmt', required: get_option('nls'))
if msgfmt.found()
source_root = meson.current_source_dir()
@ -191,7 +180,6 @@ endif
subdir('include')
subdir('src')
subdir('docs')
subdir('clients')
dep_cmocka = dependency('cmocka', required: get_option('test'))
if dep_cmocka.found()
@ -204,13 +192,16 @@ executable(
include_directories: [labwc_inc],
dependencies: labwc_deps,
install: true,
link_args: link_args,
)
install_data('data/labwc.desktop', install_dir: get_option('datadir') / 'wayland-sessions')
install_data('data/labwc-portals.conf', install_dir: get_option('datadir') / 'xdg-desktop-portal')
# TODO: move this to clients/meson.build after the labnag PR
clients = files('clients/lab-sensible-terminal')
install_data(clients, install_dir: get_option('bindir'))
icons = ['labwc-symbolic.svg', 'labwc.svg']
foreach icon : icons
icon_path = join_paths('data', icon)

View file

@ -5,4 +5,3 @@ option('icon', type: 'feature', value: 'enabled', description: 'Enable window ic
option('nls', type: 'feature', value: 'auto', description: 'Enable native language support')
option('static_analyzer', type: 'feature', value: 'disabled', description: 'Run gcc static analyzer')
option('test', type: 'feature', value: 'disabled', description: 'Run tests')
option('sections', type: 'feature', value: 'disabled', description: 'Show unused functions')

View file

@ -1 +1 @@
ar ca cs da de el es et eu fa fi fr gl hu id it ja ka ko lt ms nl pa pl pt pt_BR ru sk sv tr uk zh_CN zh_TW
ar ca cs da de el es et eu fa fi fr gl hu id it ja ka ko lt ms nl pa pl pt pt_BR ru sk sv tr uk zh_CN

View file

@ -8,16 +8,14 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-07-17 07:22+0000\n"
"PO-Revision-Date: 2024-09-23 20:01+0000\n"
"Last-Translator: Abdullah Albaroty <albaroty@gmail.com>\n"
"Language-Team: Arabic <https://translate.lxqt-project.org/projects/labwc/"
"labwc/ar/>\n"
"Language-Team: Arabic <https://translate.lxqt-project.org/projects/labwc/labwc/ar/>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 4.2.1\n"
#: src/menu/menu.c:1016
@ -26,7 +24,7 @@ msgstr "اذهب هناك..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "الطرفية"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-10-11 20:01+0000\n"
"Last-Translator: alvaroelpob <alvaropobladoresteban9@gmail.com>\n"
"Language-Team: Catalan <https://translate.lxqt-project.org/projects/labwc/"
"labwc/ca/>\n"
"PO-Revision-Date: 2025-03-29 11:25+0000\n"
"Last-Translator: Davidmp <opensusecatala@gmail.com>\n"
"Language-Team: Catalan <https://translate.lxqt-project.org/projects/labwc/labwc/ca/>\n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Ves-hi..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminal"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,32 +8,29 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-10-11 20:01+0000\n"
"Last-Translator: p-bo <pavel.borecki@gmail.com>\n"
"Language-Team: Czech <https://translate.lxqt-project.org/projects/labwc/"
"labwc/cs/>\n"
"PO-Revision-Date: 2024-03-02 02:00+0100\n"
"Last-Translator: zenobit <zenobit@disroot.org>\n"
"Language-Team: Czech <zenobit@disroot.org>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 4.2.1\n"
#: src/menu/menu.c:1016
msgid "Go there..."
msgstr "Přejít tam..."
msgstr ""
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminál"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"
msgstr "Přenastavit"
msgstr "Překonfigurovat"
#: src/menu/menu.c:1042
msgid "Exit"
msgstr "Ukončit"
msgstr "Odejít"
#: src/menu/menu.c:1056
msgid "Minimize"
@ -49,7 +46,7 @@ msgstr "Na celou obrazovku"
#: src/menu/menu.c:1062
msgid "Roll Up/Down"
msgstr "Posouvat nahoru/dolů"
msgstr "Rolovat nahoru/dolů"
#: src/menu/menu.c:1064
msgid "Decorations"
@ -69,11 +66,11 @@ msgstr "Posunout doprava"
#: src/menu/menu.c:1083
msgid "Always on Visible Workspace"
msgstr "Vždy na viditelné Pracovní ploše"
msgstr "Vždy na viditelné Pracovní Ploše"
#: src/menu/menu.c:1086
msgid "Workspace"
msgstr "Pracovní plocha"
msgstr "Pracovní Plocha"
#: src/menu/menu.c:1089
msgid "Close"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-08-15 20:01+0000\n"
"PO-Revision-Date: 2024-11-05 21:01+0000\n"
"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
"Language-Team: German <https://translate.lxqt-project.org/projects/labwc/"
"labwc/de/>\n"
"Language-Team: German <https://translate.lxqt-project.org/projects/labwc/labwc/de/>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Dorthin gehen..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminal"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-08-02 08:01+0000\n"
"Last-Translator: Dimitrios Glentadakis <dglent@free.fr>\n"
"Language-Team: Greek <https://translate.lxqt-project.org/projects/labwc/"
"labwc/el/>\n"
"PO-Revision-Date: 2024-09-25 20:01+0000\n"
"Last-Translator: Giannis Antypas <gianni.antypas@gmail.com>\n"
"Language-Team: Greek <https://translate.lxqt-project.org/projects/labwc/labwc/el/>\n"
"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Πήγαινε εκεί..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Τερματικό"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-08-11 00:27+0000\n"
"Last-Translator: Oliver Chiasson <olivierchiasson@hotmail.fr>\n"
"Language-Team: French <https://translate.lxqt-project.org/projects/labwc/"
"labwc/fr/>\n"
"PO-Revision-Date: 2024-12-15 01:13+0000\n"
"Last-Translator: vTT <vttfreebsd@gmail.com>\n"
"Language-Team: French <https://translate.lxqt-project.org/projects/labwc/labwc/fr/>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Y aller…"
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminal"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-08-02 03:27+0000\n"
"PO-Revision-Date: 2024-12-10 02:04+0000\n"
"Last-Translator: 이정희 <daemul72@gmail.com>\n"
"Language-Team: Korean <https://translate.lxqt-project.org/projects/labwc/"
"labwc/ko/>\n"
"Language-Team: Korean <https://translate.lxqt-project.org/projects/labwc/labwc/ko/>\n"
"Language: ko\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "빨리 가기..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "터미널"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,17 +8,14 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-07-19 18:47+0000\n"
"PO-Revision-Date: 2024-11-13 21:01+0000\n"
"Last-Translator: Moo <hazap@hotmail.com>\n"
"Language-Team: Lithuanian <https://translate.lxqt-project.org/projects/labwc/"
"labwc/lt/>\n"
"Language-Team: Lithuanian <https://translate.lxqt-project.org/projects/labwc/labwc/lt/>\n"
"Language: lt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n % 10 == 1 && (n % 100 < 11 || n % 100 > "
"19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? "
"1 : 2);\n"
"Plural-Forms: nplurals=3; plural=(n % 10 == 1 && (n % 100 < 11 || n % 100 > 19)) ? 0 : ((n % 10 >= 2 && n % 10 <= 9 && (n % 100 < 11 || n % 100 > 19)) ? 1 : 2);\n"
"X-Generator: Weblate 4.2.1\n"
#: src/menu/menu.c:1016
@ -27,7 +24,7 @@ msgstr "Eiti ten..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminalas"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-08-18 20:01+0000\n"
"PO-Revision-Date: 2025-04-08 05:25+0000\n"
"Last-Translator: Qayyum Yazid <purrnama@proton.me>\n"
"Language-Team: Malay <https://translate.lxqt-project.org/projects/labwc/"
"labwc/ms/>\n"
"Language-Team: Malay <https://translate.lxqt-project.org/projects/labwc/labwc/ms/>\n"
"Language: ms\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Pergi sana..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminal"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-07-13 08:01+0000\n"
"PO-Revision-Date: 2024-09-21 20:01+0000\n"
"Last-Translator: Hugo Carvalho <hugokarvalho@hotmail.com>\n"
"Language-Team: Portuguese <https://translate.lxqt-project.org/projects/labwc/"
"labwc/pt/>\n"
"Language-Team: Portuguese <https://translate.lxqt-project.org/projects/labwc/labwc/pt/>\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Ir lá..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminal"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,10 +8,9 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-09-06 04:27+0000\n"
"Last-Translator: virtual-hand <handvirtual@tutamail.com>\n"
"Language-Team: Portuguese (Brazil) <https://translate.lxqt-project.org/"
"projects/labwc/labwc/pt_BR/>\n"
"PO-Revision-Date: 2025-02-04 21:01+0000\n"
"Last-Translator: EggSupernova <leomelo34@protonmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://translate.lxqt-project.org/projects/labwc/labwc/pt_BR/>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -25,7 +24,7 @@ msgstr "Vá para..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Terminal"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,16 +8,14 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-07-30 08:01+0000\n"
"Last-Translator: Valera <ValeraDX@yandex.ru>\n"
"Language-Team: Russian <https://translate.lxqt-project.org/projects/labwc/"
"labwc/ru/>\n"
"PO-Revision-Date: 2024-12-08 21:01+0000\n"
"Last-Translator: unabomberlive <7alinchik@mail.ru>\n"
"Language-Team: Russian <https://translate.lxqt-project.org/projects/labwc/labwc/ru/>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 4.2.1\n"
#: src/menu/menu.c:1016
@ -26,7 +24,7 @@ msgstr "Перейти..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Терминал"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

View file

@ -8,16 +8,14 @@ msgstr ""
"Project-Id-Version: labwc\n"
"Report-Msgid-Bugs-To: https://github.com/labwc/labwc/issues\n"
"POT-Creation-Date: 2024-09-19 21:09+1000\n"
"PO-Revision-Date: 2025-08-16 20:01+0000\n"
"PO-Revision-Date: 2024-09-24 08:01+0000\n"
"Last-Translator: Ihor Hordiichuk <igor_ck@outlook.com>\n"
"Language-Team: Ukrainian <https://translate.lxqt-project.org/projects/labwc/"
"labwc/uk/>\n"
"Language-Team: Ukrainian <https://translate.lxqt-project.org/projects/labwc/labwc/uk/>\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 4.2.1\n"
#: src/menu/menu.c:1016
@ -26,7 +24,7 @@ msgstr "Перейти до..."
#: src/menu/menu.c:1034
msgid "Terminal"
msgstr "Термінал"
msgstr ""
#: src/menu/menu.c:1040
msgid "Reconfigure"

Some files were not shown because too many files have changed in this diff Show more