forked from speedie/spmenu
Add experimental native Wayland support
This commit is contained in:
parent
7ca66d674f
commit
692e3abc68
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,6 +2,8 @@
|
|||
*.o
|
||||
*zst*
|
||||
*sig*
|
||||
*gz*
|
||||
*tar*
|
||||
spmenu
|
||||
buildconf_dev
|
||||
buildconf
|
||||
|
|
30
PKGBUILD
30
PKGBUILD
|
@ -3,21 +3,43 @@
|
|||
pkgname=spmenu
|
||||
pkgver=VERSION
|
||||
pkgrel=1
|
||||
pkgdesc="Fancy dynamic menu, compatible with dmenu!"
|
||||
pkgdesc="Fancy dynamic menu for X11 and Wayland, compatible with dmenu!"
|
||||
url="https://spmenu.speedie.site"
|
||||
arch=(i686 x86_64)
|
||||
license=(MIT)
|
||||
depends=(sh libxinerama cairo pango libx11 imlib2 fribidi libconfig)
|
||||
makedepends=(git meson ninja)
|
||||
depends=(
|
||||
sh
|
||||
libxinerama
|
||||
cairo
|
||||
pango
|
||||
wayland
|
||||
wayland-protocols
|
||||
libxkbcommon
|
||||
libx11
|
||||
imlib2
|
||||
fribidi
|
||||
libconfig
|
||||
)
|
||||
|
||||
makedepends=(
|
||||
git
|
||||
meson
|
||||
ninja
|
||||
)
|
||||
|
||||
provides=($pkgname)
|
||||
conflicts=($pkgname)
|
||||
source=(
|
||||
"$pkgname-$pkgver.tar.gz"
|
||||
"$pkgname-$pkgver.tar.gz.sig"
|
||||
#"https://ls.speedie.site/releases/$pkgname/$pkgname-$pkgver.tar.gz"
|
||||
#"https://ls.speedie.site/releases/$pkgname/$pkgname-$pkgver.tar.gz.sig"
|
||||
)
|
||||
|
||||
md5sums=(MD5SUM 'SKIP')
|
||||
md5sums=(
|
||||
MD5SUM
|
||||
'SKIP'
|
||||
)
|
||||
|
||||
build(){
|
||||
cd $pkgname-$pkgver
|
||||
|
|
76
README.html
76
README.html
|
@ -174,9 +174,9 @@
|
|||
</figure>
|
||||
<h1 id="spmenu">spmenu</h1>
|
||||
<h2 id="what-is-spmenu">What is spmenu?</h2>
|
||||
<p>spmenu is an X11 menu application which takes standard input, parses
|
||||
it, and lets the user choose an option and sends the selected option to
|
||||
standard output.</p>
|
||||
<p>spmenu is a simple X11 and Wayland menu application which takes
|
||||
standard input, parses it, lets the user choose an option and sends the
|
||||
selected option to standard output.</p>
|
||||
<p>In addition to this, it also serves as a run launcher through the
|
||||
included shell script <code>spmenu_run</code>, which handles both $PATH
|
||||
listing, .desktop entries and file listing.</p>
|
||||
|
@ -185,10 +185,28 @@ dmenu, spmenu introduces many new features which can be useful in shell
|
|||
scripting. There are way too many to list, but spmenu has a <a
|
||||
href="https://spmenu.speedie.site">wiki</a> which goes through features
|
||||
in more detail.</p>
|
||||
<p>It also serves as a dmenu replacement for Wayland users.</p>
|
||||
<h2 id="dependencies">Dependencies</h2>
|
||||
<ul>
|
||||
<li>wayland-client
|
||||
<ul>
|
||||
<li>For Wayland support, which is optional.</li>
|
||||
</ul></li>
|
||||
<li>wayland-scanner
|
||||
<ul>
|
||||
<li>For Wayland support, which is optional.</li>
|
||||
</ul></li>
|
||||
<li>wayland-protocols
|
||||
<ul>
|
||||
<li>For Wayland support, which is optional.</li>
|
||||
</ul></li>
|
||||
<li>xkbcommon
|
||||
<ul>
|
||||
<li>For Wayland support, which is optional.</li>
|
||||
</ul></li>
|
||||
<li>libX11
|
||||
<ul>
|
||||
<li>For X11 support</li>
|
||||
<li>If you’re using macOS, XQuartz is a dependency instead.</li>
|
||||
<li>If you’re using Wayland, <code>xorg-xwayland</code> is a
|
||||
dependency.</li>
|
||||
|
@ -274,10 +292,36 @@ instead.</p>
|
|||
<p>See <a
|
||||
href="https://spmenu.speedie.site/index.php/Using+spmenu+on+macOS">this
|
||||
wiki article</a> for more information.</p>
|
||||
<h2 id="wayland-support">Wayland support</h2>
|
||||
<p>Note that Wayland support is still experimental, and some features do
|
||||
not currently work under Wayland. Some will never work under Wayland due
|
||||
to limitations. These are:</p>
|
||||
<ul>
|
||||
<li>Image support
|
||||
<ul>
|
||||
<li>Images simply will not be drawn on Wayland.</li>
|
||||
<li>Will eventually be solved by replacing imlib2 with cairo.</li>
|
||||
</ul></li>
|
||||
<li><code>--x-position</code> and <code>--y-position</code> arguments
|
||||
<ul>
|
||||
<li>These arguments do not work under Wayland, because the layer_shell
|
||||
protocol doesn’t allow clients to be placed on a specific position.</li>
|
||||
</ul></li>
|
||||
<li>Embedding <code>-w</code> and window manager managed
|
||||
<code>-wm</code>
|
||||
<ul>
|
||||
<li>These arguments do not make much sense on Wayland, and embedding is
|
||||
not possible due to the original implementation using XEmbed. If the
|
||||
embed argument is passed it will simply be ignored and the window will
|
||||
be layered as normal.</li>
|
||||
</ul></li>
|
||||
<li><code>--monitor</code> argument</li>
|
||||
<li>Window borders</li>
|
||||
<li>Pasting</li>
|
||||
</ul>
|
||||
<h2 id="todo">TODO</h2>
|
||||
<p>Pull requests would be greatly appreciated for any of these
|
||||
issues!</p>
|
||||
<h3 id="general">General</h3>
|
||||
<ul>
|
||||
<li>Image support: Stop using OpenSSL for caching images, mostly because
|
||||
MD5() is deprecated as of OpenSSL 3.0, but this would also make it very
|
||||
|
@ -290,29 +334,9 @@ easy to have LibreSSL compatibility.</li>
|
|||
</ul></li>
|
||||
<li>Matching: Add support for contextual completions similar to
|
||||
xprompt</li>
|
||||
<li>Matching: Regex matching
|
||||
<ul>
|
||||
<li>Probably use some minimal public domain library for this, I’d like
|
||||
to avoid adding more external dependencies unless it’s a common
|
||||
dependency most people already have.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<h3
|
||||
id="unlikely-but-maybe-at-some-point-in-the-distant-future">Unlikely,
|
||||
but maybe at some point in the distant future</h3>
|
||||
<ul>
|
||||
<li>Matching: Regex matching</li>
|
||||
<li>X11: Move from Xlib to libXcb</li>
|
||||
<li>Wayland: Wayland support, but only if it doesn’t require writing any
|
||||
extra code which as of now seems unlikely, or if someone makes a patch.
|
||||
<ul>
|
||||
<li>Before this can even be done, deal with keybinds in some Wayland
|
||||
compatible way, remove .Xresources usage and figure out a way to
|
||||
preserve X11 compatibility as I do not want to use Wayland as of
|
||||
now.</li>
|
||||
<li>You can just use XWayland anyway if you happen to use Wayland, so
|
||||
it’s not like you will be unable to use spmenu in its current
|
||||
state.</li>
|
||||
</ul></li>
|
||||
<li>Wayland: Anything listed as broken under ‘Wayland support’.</li>
|
||||
</ul>
|
||||
<h2 id="scripts">Scripts</h2>
|
||||
<p>There’s a page dedicated to user scripts <a
|
||||
|
|
52
README.md
52
README.md
|
@ -5,9 +5,8 @@ spmenu
|
|||
|
||||
## What is spmenu?
|
||||
|
||||
spmenu is an X11 menu application which takes standard input, parses
|
||||
it, and lets the user choose an option and sends the
|
||||
selected option to standard output.
|
||||
spmenu is a simple X11 and Wayland menu application which takes standard input, parses
|
||||
it, lets the user choose an option and sends the selected option to standard output.
|
||||
|
||||
In addition to this, it also serves as a run launcher through the included
|
||||
shell script `spmenu_run`, which handles both $PATH listing, .desktop entries
|
||||
|
@ -18,9 +17,20 @@ spmenu introduces many new features which can be useful in shell scripting.
|
|||
There are way too many to list, but spmenu has a
|
||||
[wiki](https://spmenu.speedie.site) which goes through features in more detail.
|
||||
|
||||
It also serves as a dmenu replacement for Wayland users.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- wayland-client
|
||||
- For Wayland support, which is optional.
|
||||
- wayland-scanner
|
||||
- For Wayland support, which is optional.
|
||||
- wayland-protocols
|
||||
- For Wayland support, which is optional.
|
||||
- xkbcommon
|
||||
- For Wayland support, which is optional.
|
||||
- libX11
|
||||
- For X11 support
|
||||
- If you're using macOS, XQuartz is a dependency instead.
|
||||
- If you're using Wayland, `xorg-xwayland` is a dependency.
|
||||
- libXrender
|
||||
|
@ -108,12 +118,30 @@ directory**. If you want to generate a Pacman package, run
|
|||
See [this wiki article](https://spmenu.speedie.site/index.php/Using+spmenu+on+macOS)
|
||||
for more information.
|
||||
|
||||
## Wayland support
|
||||
|
||||
Note that Wayland support is still experimental, and some features do not
|
||||
currently work under Wayland. Some will never work under Wayland due to limitations.
|
||||
These are:
|
||||
|
||||
- Image support
|
||||
- Images simply will not be drawn on Wayland.
|
||||
- Will eventually be solved by replacing imlib2 with cairo.
|
||||
- `--x-position` and `--y-position` arguments
|
||||
- These arguments do not work under Wayland, because the layer_shell
|
||||
protocol doesn't allow clients to be placed on a specific position.
|
||||
- Embedding `-w` and window manager managed `-wm`
|
||||
- These arguments do not make much sense on Wayland, and embedding is not possible
|
||||
due to the original implementation using XEmbed. If the embed argument is passed
|
||||
it will simply be ignored and the window will be layered as normal.
|
||||
- `--monitor` argument
|
||||
- Window borders
|
||||
- Pasting
|
||||
|
||||
## TODO
|
||||
|
||||
Pull requests would be greatly appreciated for any of these issues!
|
||||
|
||||
### General
|
||||
|
||||
- Image support: Stop using OpenSSL for caching images, mostly because MD5()
|
||||
is deprecated as of OpenSSL 3.0, but this would also make it very easy to
|
||||
have LibreSSL compatibility.
|
||||
|
@ -123,20 +151,8 @@ have LibreSSL compatibility.
|
|||
for each added line.
|
||||
- Matching: Add support for contextual completions similar to xprompt
|
||||
- Matching: Regex matching
|
||||
- Probably use some minimal public domain library for this, I'd
|
||||
like to avoid adding more external dependencies unless it's a
|
||||
common dependency most people already have.
|
||||
|
||||
### Unlikely, but maybe at some point in the distant future
|
||||
|
||||
- X11: Move from Xlib to libXcb
|
||||
- Wayland: Wayland support, but only if it doesn't require writing any extra
|
||||
code which as of now seems unlikely, or if someone makes a patch.
|
||||
- Before this can even be done, deal with keybinds in some Wayland compatible
|
||||
way, remove .Xresources usage and figure out a way to preserve X11
|
||||
compatibility as I do not want to use Wayland as of now.
|
||||
- You can just use XWayland anyway if you happen to use Wayland, so it's not
|
||||
like you will be unable to use spmenu in its current state.
|
||||
- Wayland: Anything listed as broken under 'Wayland support'.
|
||||
|
||||
## Scripts
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>spmenu documentation 1.2.1</title>
|
||||
<title>spmenu documentation 2.0</title>
|
||||
<style>
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
|
@ -166,7 +166,7 @@
|
|||
</head>
|
||||
<body>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">spmenu documentation 1.2.1</h1>
|
||||
<h1 class="title">spmenu documentation 2.0</h1>
|
||||
</header>
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<ul>
|
||||
|
|
41
docs/docs.md
41
docs/docs.md
|
@ -1,9 +1,8 @@
|
|||
spmenu
|
||||
======
|
||||
|
||||
spmenu is an X11 menu application which takes standard input, parses
|
||||
it, and lets the user choose an option and sends the
|
||||
selected option to standard output.
|
||||
spmenu is an X11 and Wayland menu application which takes standard input, parses
|
||||
it, lets the user choose an option and sends the selected option to standard output.
|
||||
|
||||
In addition to this, it also serves as a run launcher through the included
|
||||
shell script `spmenu_run`, which handles both $PATH listing, .desktop entries
|
||||
|
@ -13,6 +12,8 @@ using spmenu as a run launcher.
|
|||
While spmenu is based on dmenu, and is also fully compatible with dmenu,
|
||||
spmenu introduces many new features which can be useful in shell scripting.
|
||||
|
||||
It also serves as a dmenu replacement for Wayland users.
|
||||
|
||||
## Usage
|
||||
|
||||
On runtime, spmenu reads from standard input (stdin). spmenu items are
|
||||
|
@ -54,12 +55,6 @@ You may use long, descriptive arguments or the shorter arguments.
|
|||
`-cd, --cache-dir dir`
|
||||
: Set cache directory to dir
|
||||
|
||||
`-rw, --relative-width`
|
||||
: Enable relative input width
|
||||
|
||||
`-nrw, --no-relative-width`
|
||||
: Disable relative input width
|
||||
|
||||
`-ix, --print-index`
|
||||
: Print index instead of actual text
|
||||
|
||||
|
@ -360,6 +355,12 @@ You may use long, descriptive arguments or the shorter arguments.
|
|||
`-nltm, --no-load-theme`
|
||||
: Don't load theme (~/.config/spmenu/theme.conf) on runtime
|
||||
|
||||
`-x11, --x11`
|
||||
: Run spmenu in X11 mode
|
||||
|
||||
`-wl, --wayland`
|
||||
: Run spmenu in Wayland mode
|
||||
|
||||
`-v, --version`
|
||||
: Print spmenu version to stdout
|
||||
|
||||
|
@ -756,6 +757,8 @@ These are the default keybinds. You can generate these yourself from a
|
|||
|
||||
## .Xresources
|
||||
|
||||
**NOTE: Only applies for X11 users**
|
||||
|
||||
spmenu also has .Xresources (xrdb) support built in. It reads the xrdb
|
||||
(.Xresources database) on runtime. You may disable it by passing -nxrdb,
|
||||
or enable it by padding -xrdb. You can also set this in the config file.
|
||||
|
@ -825,6 +828,26 @@ run `printf 'spmenu:version' | spmenu`. There are a few of these.
|
|||
`spmenu:license`
|
||||
: Print the spmenu license
|
||||
|
||||
## Wayland support
|
||||
|
||||
Note that Wayland support is still experimental, and some features do not
|
||||
currently work under Wayland. Some will never work under Wayland due to limitations.
|
||||
These are:
|
||||
|
||||
- Image support
|
||||
- Images simply will not be drawn on Wayland.
|
||||
- Will eventually be solved by replacing imlib2 with cairo.
|
||||
- `--x-position` and `--y-position` arguments
|
||||
- These arguments do not work under Wayland, because the layer_shell
|
||||
protocol doesn't allow clients to be placed on a specific position.
|
||||
- Embedding `-w` and window manager managed `-wm`
|
||||
- These arguments do not make much sense on Wayland, and embedding is not possible
|
||||
due to the original implementation using XEmbed. If the embed argument is passed
|
||||
it will simply be ignored and the window will be layered as normal.
|
||||
- `--monitor` argument
|
||||
- Window borders
|
||||
- Pasting
|
||||
|
||||
## License
|
||||
|
||||
spmenu is licensed under the MIT license because that's the original suckless
|
||||
|
|
|
@ -141,7 +141,6 @@ spmenu.menumarginh: 0
|
|||
spmenu.xpos: 0
|
||||
spmenu.ypos: 0
|
||||
spmenu.minwidth: 1000
|
||||
spmenu.accuratewidth: 0
|
||||
spmenu.borderwidth: 0
|
||||
|
||||
!! Properties
|
||||
|
|
|
@ -21,6 +21,7 @@ spmenu = {
|
|||
monitor = -1; // Monitor to spawn spmenu on, (-1, 0, 1, ...)
|
||||
managed = 0; // Allow your window manager to manage spmenu as a window (0/1)
|
||||
alpha = 1; // Enable alpha/transparency (0/1)
|
||||
protocol = 1; // Protocol to attempt to use by default (0: X11, 1: Wayland)
|
||||
} );
|
||||
|
||||
/* X11 properties */
|
||||
|
@ -167,7 +168,6 @@ spmenu = {
|
|||
fuzzy = 1; // Enable fuzzy finding (0/1)
|
||||
preselected = 0; // Preselect an item, 0 is the first item (number)
|
||||
mark = 1; // Allow marking/selecting multiple items (0/1)
|
||||
accuratewidth = 0; // Enable accurate width, could be noticeably slower in some cases (0/1)
|
||||
delimiters = " "; // Word delimiter, used to delete words (text)
|
||||
listfile = "NULL"; // File to read entries from. If set to NULL standard input is read. This is read every time a key is pressed. (text)
|
||||
} );
|
||||
|
@ -241,35 +241,30 @@ spmenu = {
|
|||
*/
|
||||
mouse = ( // Left click on input: Clear the input
|
||||
{ click = "ClickInput";
|
||||
modifier = "None";
|
||||
button = "Left Click";
|
||||
function = "clear";
|
||||
argument = "0";
|
||||
},
|
||||
// Left click on prompt: Clear the input
|
||||
{ click = "ClickPrompt";
|
||||
modifier = "None";
|
||||
button = "Left Click";
|
||||
function = "clear";
|
||||
argument = "0";
|
||||
},
|
||||
// Left click on the mode indicator: Toggle mode
|
||||
{ click = "ClickMode";
|
||||
modifier = "None";
|
||||
button = "Left Click";
|
||||
function = "switchmode";
|
||||
argument = "0";
|
||||
},
|
||||
// Click on the match count: Toggle viewing history buffer
|
||||
{ click = "ClickNumber";
|
||||
modifier = "None";
|
||||
button = "Left Click";
|
||||
function = "viewhist";
|
||||
argument = "0";
|
||||
},
|
||||
// Left click on an item: Select it
|
||||
{ click = "ClickSelItem";
|
||||
modifier = "None";
|
||||
button = "Left Click";
|
||||
function = "None";
|
||||
argument = "0";
|
||||
|
|
78
keybinds.h
78
keybinds.h
|
@ -5,6 +5,7 @@
|
|||
* See LICENSE file for copyright and license details.
|
||||
*/
|
||||
|
||||
/* X11 hardcoded keybinds */
|
||||
static Key keys[] = {
|
||||
/* mode modifier key function argument
|
||||
*
|
||||
|
@ -78,3 +79,80 @@ static Key keys[] = {
|
|||
/* insert mode */
|
||||
{ 1, 0, XK_Escape, switchmode, {0} },
|
||||
};
|
||||
|
||||
/* Wayland hardcoded keybinds */
|
||||
#if USEWAYLAND
|
||||
static WlKey wl_keys[] = {
|
||||
/* mode modifier key function argument
|
||||
*
|
||||
* any mode
|
||||
*/
|
||||
{ -1, WL_None, XKB_KEY_Return, selectitem, {.i = +1 } },
|
||||
{ -1, WL_Shift, XKB_KEY_Return, selectitem, {0} },
|
||||
{ -1, WL_Ctrl, XKB_KEY_Return, markitem, {0} },
|
||||
{ -1, WL_None, XKB_KEY_Tab, complete, {0} },
|
||||
{ -1, WL_Ctrl, XKB_KEY_v, paste, {.i = 2 } },
|
||||
{ -1, WL_CtrlShift, XKB_KEY_v, paste, {.i = 1 } },
|
||||
{ -1, WL_None, XKB_KEY_BackSpace, backspace, {0} },
|
||||
{ -1, WL_Ctrl, XKB_KEY_BackSpace, deleteword, {0} },
|
||||
{ -1, WL_Ctrl, XKB_KEY_Left, moveword, {.i = -1 } },
|
||||
{ -1, WL_Ctrl, XKB_KEY_Right, moveword, {.i = +1 } },
|
||||
{ -1, WL_None, XKB_KEY_Left, movecursor, {.i = -1 } },
|
||||
{ -1, WL_None, XKB_KEY_Right, movecursor, {.i = +1 } },
|
||||
{ -1, WL_CtrlShift, XKB_KEY_p, setprofile, {0} },
|
||||
|
||||
/* normal mode */
|
||||
{ 0, WL_None, XKB_KEY_i, switchmode, {0} },
|
||||
{ 0, WL_None, XKB_KEY_slash, switchmode, {0} },
|
||||
{ 0, WL_Ctrl, XKB_KEY_equal, setimgsize, {.i = +1 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_minus, setimgsize, {.i = -1 } },
|
||||
{ 0, WL_None, XKB_KEY_equal, setimgsize, {.i = +10 } },
|
||||
{ 0, WL_None, XKB_KEY_minus, setimgsize, {.i = -10 } },
|
||||
{ 0, WL_Shift, XKB_KEY_equal, setimgsize, {.i = +100 } },
|
||||
{ 0, WL_Shift, XKB_KEY_minus, setimgsize, {.i = -100 } },
|
||||
{ 0, WL_Shift, XKB_KEY_0, defaultimg, {0} },
|
||||
{ 0, WL_None, XKB_KEY_r, rotateimg, {0} },
|
||||
{ 0, WL_None, XKB_KEY_o, setimgpos, {.i = +1 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_1, setimggaps, {.i = -1 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_2, setimggaps, {.i = +1 } },
|
||||
{ 0, WL_None, XKB_KEY_1, setimggaps, {.i = -10 } },
|
||||
{ 0, WL_None, XKB_KEY_2, setimggaps, {.i = +10 } },
|
||||
{ 0, WL_Shift, XKB_KEY_1, setimggaps, {.i = -100 } },
|
||||
{ 0, WL_Shift, XKB_KEY_2, setimggaps, {.i = +100 } },
|
||||
{ 0, WL_None, XKB_KEY_t, toggleimg, {0} },
|
||||
{ 0, WL_None, XKB_KEY_f, togglefullimg, {0} },
|
||||
{ 0, WL_None, XKB_KEY_p, paste, {.i = 2 } },
|
||||
{ 0, WL_None, XKB_KEY_h, flipimg, {.i = 1 } },
|
||||
{ 0, WL_None, XKB_KEY_v, flipimg, {.i = 0 } },
|
||||
{ 0, WL_None, XKB_KEY_k, moveup, {0} },
|
||||
{ 0, WL_None, XKB_KEY_j, movedown, {0} },
|
||||
{ 0, WL_None, XKB_KEY_h, moveleft, {0} },
|
||||
{ 0, WL_None, XKB_KEY_l, moveright, {0} },
|
||||
{ 0, WL_Ctrl, XKB_KEY_u, moveup, {.i = 5 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_d, movedown, {.i = 5 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_k, setlines, {.i = +1 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_j, setlines, {.i = -1 } },
|
||||
{ 0, WL_CtrlAltShift, XKB_KEY_k, setlines, {.i = +5 } },
|
||||
{ 0, WL_CtrlAltShift, XKB_KEY_j, setlines, {.i = -5 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_h, setcolumns, {.i = +1 } },
|
||||
{ 0, WL_Ctrl, XKB_KEY_l, setcolumns, {.i = -1 } },
|
||||
{ 0, WL_CtrlAltShift, XKB_KEY_h, setcolumns, {.i = +5 } },
|
||||
{ 0, WL_CtrlAltShift, XKB_KEY_l, setcolumns, {.i = -5 } },
|
||||
{ 0, WL_None, XKB_KEY_u, togglehighlight, {0} },
|
||||
{ 0, WL_CtrlShift, XKB_KEY_h, viewhist, {0} },
|
||||
{ 0, WL_None, XKB_KEY_d, clear, {0} },
|
||||
{ 0, WL_Shift, XKB_KEY_d, clearins, {0} },
|
||||
{ 0, WL_None, XKB_KEY_Escape, quit, {0} },
|
||||
{ 0, WL_None, XKB_KEY_Home, movestart, {0} },
|
||||
{ 0, WL_None, XKB_KEY_End, moveend, {0} },
|
||||
{ 0, WL_None, XKB_KEY_g, movestart, {0} },
|
||||
{ 0, WL_Shift, XKB_KEY_g, moveend, {0} },
|
||||
{ 0, WL_None, XKB_KEY_Next, movenext, {0} },
|
||||
{ 0, WL_None, XKB_KEY_Prior, moveprev, {0} },
|
||||
{ 0, WL_Alt, XKB_KEY_p, navhistory, {.i = -1 } },
|
||||
{ 0, WL_Alt, XKB_KEY_n, navhistory, {.i = +1 } },
|
||||
|
||||
/* insert mode */
|
||||
{ 1, WL_None, XKB_KEY_Escape, switchmode, {0} },
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -159,8 +159,10 @@ void moveend(Arg *arg) {
|
|||
}
|
||||
|
||||
void paste(Arg *arg) {
|
||||
if (!protocol) {
|
||||
paste_x11(arg->i);
|
||||
}
|
||||
}
|
||||
|
||||
void viewhist(Arg *arg) {
|
||||
int i;
|
||||
|
@ -480,6 +482,7 @@ void setlines(Arg *arg) {
|
|||
}
|
||||
|
||||
resizeclient();
|
||||
calcoffsets();
|
||||
drawmenu();
|
||||
}
|
||||
|
||||
|
@ -497,6 +500,7 @@ void setcolumns(Arg *arg) {
|
|||
}
|
||||
|
||||
resizeclient();
|
||||
calcoffsets();
|
||||
drawmenu();
|
||||
}
|
||||
|
||||
|
|
132
libs/argv.c
132
libs/argv.c
|
@ -19,6 +19,10 @@ void readargs(int argc, char *argv[]) {
|
|||
loadbinds = 1;
|
||||
} else if (!strcmp(argv[j], "-nlbi") || (!strcmp(argv[j], "--no-load-binds"))) {
|
||||
loadbinds = 0;
|
||||
} else if (!strcmp(argv[j], "-x11") || (!strcmp(argv[j], "--x11"))) {
|
||||
protocol = 0;
|
||||
} else if (!strcmp(argv[j], "-wl") || (!strcmp(argv[j], "--wayland"))) {
|
||||
protocol = 1;
|
||||
#if USECONFIG
|
||||
} else if (!strcmp(argv[j], "-cf") || (!strcmp(argv[j], "--config-file"))) { // specify a config file
|
||||
if (argv[j+1]) {
|
||||
|
@ -59,7 +63,7 @@ void readargs(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// init/read xrdb
|
||||
if (xresources) {
|
||||
if (xresources && !protocol) {
|
||||
#if USEXRESOURCES
|
||||
XrmInitialize();
|
||||
load_xresources();
|
||||
|
@ -110,10 +114,6 @@ void readargs(int argc, char *argv[]) {
|
|||
mark = 1;
|
||||
} else if (!strcmp(argv[i], "-nma") || (!strcmp(argv[i], "--no-mark-items"))) { // don't allow marking items
|
||||
mark = 0;
|
||||
} else if (!strcmp(argv[i], "-rw") || (!strcmp(argv[i], "--relative-width"))) { // relative width
|
||||
accuratewidth = 1;
|
||||
} else if (!strcmp(argv[i], "-nrw") || (!strcmp(argv[i], "--no-relative-width"))) { // no relative width
|
||||
accuratewidth = 0;
|
||||
} else if (!strcmp(argv[i], "-F") || (!strcmp(argv[i], "--fuzzy"))) { // fuzzy matching
|
||||
fuzzy = 1;
|
||||
} else if (!strcmp(argv[i], "-NF") || (!strcmp(argv[i], "--no-fuzzy"))) { // no fuzzy matching
|
||||
|
@ -226,6 +226,10 @@ void readargs(int argc, char *argv[]) {
|
|||
|| !strcmp(argv[i], "--no-load-theme")
|
||||
|| !strcmp(argv[i], "-lbi")
|
||||
|| !strcmp(argv[i], "-nlbi")
|
||||
|| !strcmp(argv[i], "-wl")
|
||||
|| !strcmp(argv[i], "--wayland")
|
||||
|| !strcmp(argv[i], "-x11")
|
||||
|| !strcmp(argv[i], "--x11")
|
||||
|| !strcmp(argv[i], "--load-binds")
|
||||
|| !strcmp(argv[i], "--no-load-binds")
|
||||
|| !strcmp(argv[i], "-gbc")
|
||||
|
@ -321,27 +325,29 @@ void readargs(int argc, char *argv[]) {
|
|||
|
||||
// dmenu compatibility options
|
||||
} else if (!strcmp(argv[i], "-nb")) { // normal background color
|
||||
colors[SchemeItemNorm1][ColBg] = argv[++i];
|
||||
colors[SchemeItemNorm2][ColBg] = argv[++i];
|
||||
colors[SchemeMenu][ColBg] = argv[++i];
|
||||
colors[SchemeInput][ColBg] = argv[++i];
|
||||
colors[SchemePrompt][ColBg] = argv[++i];
|
||||
int ix = ++i;
|
||||
strcpy(col_itemnormbg, argv[ix]);
|
||||
strcpy(col_itemnormbg2, argv[ix]);
|
||||
strcpy(col_menu, argv[ix]);
|
||||
strcpy(col_inputbg, argv[ix]);
|
||||
strcpy(col_promptbg, argv[ix]);
|
||||
} else if (!strcmp(argv[i], "-nf")) { // normal foreground color
|
||||
colors[SchemeItemNorm1][ColFg] = argv[++i];
|
||||
colors[SchemeItemNorm2][ColFg] = argv[++i];
|
||||
colors[SchemeMenu][ColFg] = argv[++i];
|
||||
colors[SchemeInput][ColFg] = argv[++i];
|
||||
colors[SchemePrompt][ColFg] = argv[++i];
|
||||
int ix = ++i;
|
||||
strcpy(col_itemnormfg, argv[ix]);
|
||||
strcpy(col_itemnormfg2, argv[ix]);
|
||||
strcpy(col_inputfg, argv[ix]);
|
||||
strcpy(col_promptfg, argv[ix]);
|
||||
} else if (!strcmp(argv[i], "-sb")) { // selected background color
|
||||
colors[SchemeItemSel][ColBg] = argv[++i];
|
||||
colors[SchemeMenu][ColBg] = argv[++i];
|
||||
colors[SchemeInput][ColBg] = argv[++i];
|
||||
colors[SchemePrompt][ColBg] = argv[++i];
|
||||
int ix = ++i;
|
||||
strcpy(col_itemselbg, argv[ix]);
|
||||
strcpy(col_menu, argv[ix]);
|
||||
strcpy(col_inputbg, argv[ix]);
|
||||
strcpy(col_promptbg, argv[ix]);
|
||||
} else if (!strcmp(argv[i], "-sf")) { // selected foreground color
|
||||
colors[SchemeItemSel][ColFg] = argv[++i];
|
||||
colors[SchemeMenu][ColFg] = argv[++i];
|
||||
colors[SchemeInput][ColBg] = argv[++i];
|
||||
colors[SchemePrompt][ColFg] = argv[++i];
|
||||
int ix = ++i;
|
||||
strcpy(col_itemselfg, argv[ix]);
|
||||
strcpy(col_inputfg, argv[ix]);
|
||||
strcpy(col_promptfg, argv[ix]);
|
||||
|
||||
// more
|
||||
} else if (!strcmp(argv[i], "-is") || (!strcmp(argv[i], "--image-size"))) { // image size
|
||||
|
@ -359,65 +365,65 @@ void readargs(int argc, char *argv[]) {
|
|||
|
||||
// spmenu colors
|
||||
} else if (!strcmp(argv[i], "-nif") || (!strcmp(argv[i], "--normal-item-foreground"))) { // normal item foreground color
|
||||
colors[SchemeItemNorm1][ColFg] = argv[++i];
|
||||
strcpy(col_itemnormfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nib") || (!strcmp(argv[i], "--normal-item-background"))) { // normal item background color
|
||||
colors[SchemeItemNorm1][ColBg] = argv[++i];
|
||||
strcpy(col_itemnormbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nnif") || (!strcmp(argv[i], "--normal-next-item-foreground"))) { // normal next item foreground color
|
||||
colors[SchemeItemNorm2][ColFg] = argv[++i];
|
||||
strcpy(col_itemnormfg2, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nnib") || (!strcmp(argv[i], "--normal-next-item-background"))) { // normal next item background color
|
||||
colors[SchemeItemNorm2][ColBg] = argv[++i];
|
||||
strcpy(col_itemnormbg2, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-sif") || (!strcmp(argv[i], "--selected-item-foreground"))) { // selected item foreground color
|
||||
colors[SchemeItemSel][ColFg] = argv[++i];
|
||||
strcpy(col_itemselfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-sib") || (!strcmp(argv[i], "--selected-item-background"))) { // selected item background color
|
||||
colors[SchemeItemSel][ColBg] = argv[++i];
|
||||
strcpy(col_itemselbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-npf") || (!strcmp(argv[i], "--normal-item-priority-foreground"))) { // normal item priority foreground color
|
||||
colors[SchemeItemNormPri][ColFg] = argv[++i];
|
||||
strcpy(col_itemnormprifg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-npb") || (!strcmp(argv[i], "--normal-item-priority-background"))) { // normal item priority background color
|
||||
colors[SchemeItemNormPri][ColBg] = argv[++i];
|
||||
strcpy(col_itemnormpribg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-spf") || (!strcmp(argv[i], "--selected-item-priority-foreground"))) { // selected item priority foreground color
|
||||
colors[SchemeItemSelPri][ColFg] = argv[++i];
|
||||
strcpy(col_itemselprifg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-spb") || (!strcmp(argv[i], "--selected-item-priority-background"))) { // selected item priority background color
|
||||
colors[SchemeItemSelPri][ColBg] = argv[++i];
|
||||
strcpy(col_itemselpribg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-mnbg") || (!strcmp(argv[i], "--menu-background"))) { // menu color
|
||||
colors[SchemeMenu][ColBg] = argv[++i];
|
||||
strcpy(col_menu, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-pfg") || (!strcmp(argv[i], "--prompt-foreground"))) { // prompt fg color
|
||||
colors[SchemePrompt][ColFg] = argv[++i];
|
||||
strcpy(col_promptfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-pbg") || (!strcmp(argv[i], "--prompt-background"))) { // prompt bg color
|
||||
colors[SchemePrompt][ColBg] = argv[++i];
|
||||
strcpy(col_promptbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-ifg") || (!strcmp(argv[i], "--input-foreground"))) { // input fg color
|
||||
colors[SchemeInput][ColFg] = argv[++i];
|
||||
strcpy(col_inputfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-pfg") || (!strcmp(argv[i], "--input-background"))) { // input bg color
|
||||
colors[SchemeInput][ColBg] = argv[++i];
|
||||
strcpy(col_inputbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nhb") || (!strcmp(argv[i], "--normal-highlight-background"))) { // normal highlight background color
|
||||
colors[SchemeNormHighlight][ColBg] = argv[++i];
|
||||
} else if (!strcmp(argv[i], "-shf") || (!strcmp(argv[i], "--normal-highlight-foreground"))) { // normal highlight foreground color
|
||||
colors[SchemeNormHighlight][ColFg] = argv[++i];
|
||||
} else if (!strcmp(argv[i], "-nhf") || (!strcmp(argv[i], "--selected-highlight-foreground"))) { // selected highlight foreground color
|
||||
colors[SchemeSelHighlight][ColFg] = argv[++i];
|
||||
strcpy(col_hlnormbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nhf") || (!strcmp(argv[i], "--normal-highlight-foreground"))) { // normal highlight foreground color
|
||||
strcpy(col_hlnormfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-shf") || (!strcmp(argv[i], "--selected-highlight-foreground"))) { // selected highlight foreground color
|
||||
strcpy(col_hlselfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-shb") || (!strcmp(argv[i], "--selected-highlight-background"))) { // selected highlight background color
|
||||
colors[SchemeSelHighlight][ColBg] = argv[++i];
|
||||
strcpy(col_hlselbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nbg") || (!strcmp(argv[i], "--number-background"))) { // numbg
|
||||
colors[SchemeNumber][ColBg] = argv[++i];
|
||||
strcpy(col_numbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-nfg") || (!strcmp(argv[i], "--number-foreground"))) { // numfg
|
||||
colors[SchemeNumber][ColFg] = argv[++i];
|
||||
strcpy(col_numfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-mbg") || (!strcmp(argv[i], "--mode-background"))) { // mode
|
||||
colors[SchemeMode][ColBg] = argv[++i];
|
||||
strcpy(col_modebg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-mfg") || (!strcmp(argv[i], "--mode-foreground"))) { // mode
|
||||
colors[SchemeMode][ColFg] = argv[++i];
|
||||
strcpy(col_modefg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-laf") || (!strcmp(argv[i], "--left-arrow-foreground"))) { // left arrow fg
|
||||
colors[SchemeLArrow][ColFg] = argv[++i];
|
||||
strcpy(col_larrowfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-raf") || (!strcmp(argv[i], "--right-arrow-foreground"))) { // right arrow fg
|
||||
colors[SchemeRArrow][ColFg] = argv[++i];
|
||||
strcpy(col_rarrowfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-lab") || (!strcmp(argv[i], "--left-arrow-background"))) { // left arrow bg
|
||||
colors[SchemeLArrow][ColFg] = argv[++i];
|
||||
strcpy(col_larrowbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-rab") || (!strcmp(argv[i], "--right-arrow-background"))) { // right arrow bg
|
||||
colors[SchemeRArrow][ColFg] = argv[++i];
|
||||
strcpy(col_rarrowbg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-bc") || (!strcmp(argv[i], "--border-background"))) { // border
|
||||
colors[SchemeBorder][ColBg] = argv[++i];
|
||||
strcpy(col_border, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-cc") || (!strcmp(argv[i], "-cfc")) || (!strcmp(argv[i], "--caret-foreground"))) { // caret color
|
||||
colors[SchemeCaret][ColFg] = argv[++i];
|
||||
strcpy(col_caretfg, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-cbc") || (!strcmp(argv[i], "--caret-background"))) { // caret color
|
||||
colors[SchemeCaret][ColBg] = argv[++i];
|
||||
strcpy(col_caretbg, argv[++i]);
|
||||
}
|
||||
|
||||
// sgr colors
|
||||
|
@ -452,6 +458,10 @@ void readargs(int argc, char *argv[]) {
|
|||
|| !strcmp(argv[i], "--no-load-theme")
|
||||
|| !strcmp(argv[i], "-lbi")
|
||||
|| !strcmp(argv[i], "-nlbi")
|
||||
|| !strcmp(argv[i], "-wl")
|
||||
|| !strcmp(argv[i], "--wayland")
|
||||
|| !strcmp(argv[i], "-x11")
|
||||
|| !strcmp(argv[i], "--x11")
|
||||
|| !strcmp(argv[i], "--load-binds")
|
||||
|| !strcmp(argv[i], "--no-load-binds")
|
||||
|| !strcmp(argv[i], "-gbc")
|
||||
|
@ -474,6 +484,10 @@ void readargs(int argc, char *argv[]) {
|
|||
else
|
||||
fprintf(stderr, "spmenu: Invalid argument: '%s'\n", argv[i]);
|
||||
|
||||
#if !USEWAYLAND
|
||||
protocol = 0;
|
||||
#endif
|
||||
|
||||
if (casesensitive) {
|
||||
fstrncmp = strncmp;
|
||||
fstrstr = strstr;
|
||||
|
@ -492,7 +506,9 @@ void readargs(int argc, char *argv[]) {
|
|||
|
||||
void usage(int status) {
|
||||
// print help
|
||||
fputs("spmenu: fancy dynamic menu\n\n"
|
||||
fputs("spmenu ", status ? stderr : stdout);
|
||||
fputs(VERSION, status ? stderr : stdout);
|
||||
fputs(": fancy dynamic menu\n\n"
|
||||
"- Arguments -\n"
|
||||
"spmenu -l, --lines <line> Set line count to stdin\n"
|
||||
"spmenu -mh, --line-height <height> Set spmenu line height to <height>\n"
|
||||
|
@ -502,8 +518,6 @@ void usage(int status) {
|
|||
"spmenu -ngc, --no-generate-cache Don't generate image cache\n"
|
||||
"spmenu -mc, --max-cache <size> Set max image cache size to <size>\n"
|
||||
"spmenu -cd, --cache-dir <dir> Set cache directory to <dir>\n"
|
||||
"spmenu -rw, --relative-width Enable relative input width\n"
|
||||
"spmenu -nrw, --no-relative-width Disable relative input width\n"
|
||||
"spmenu -ix, --print-index Print index instead of actual text\n"
|
||||
"spmenu -nix, --no-print-index Don't print index instead of actual text\n"
|
||||
"spmenu -f, --fast Grabs keyboard before reading stdin\n"
|
||||
|
@ -612,6 +626,8 @@ void usage(int status) {
|
|||
"spmenu -tm, --theme <theme> Load theme <theme>\n"
|
||||
"spmenu -ltm, --load-theme Load theme\n"
|
||||
"spmenu -nltm, --no-load-theme Don't load theme\n"
|
||||
"spmenu -x11, --x11 Run spmenu in X11 mode\n"
|
||||
"spmenu -wl, --wayland Run spmenu in Wayland mode\n"
|
||||
"spmenu -rv, --raw-version Print spmenu version number to stdout\n"
|
||||
"spmenu -v, --version Print spmenu version to stdout\n"
|
||||
"\n", status ? stderr : stdout);
|
||||
|
|
|
@ -1,51 +1,5 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
// alpha array
|
||||
static unsigned int alphas[][2] = {
|
||||
// fg bg
|
||||
[SchemeLArrow] = { 255, 200 },
|
||||
[SchemeRArrow] = { 255, 200 },
|
||||
[SchemeItemNorm1] = { 255, 200 },
|
||||
[SchemeItemNorm2] = { 255, 200 },
|
||||
[SchemeItemSel] = { 255, 200 },
|
||||
[SchemeItemNormPri] = { 255, 200 },
|
||||
[SchemeItemSelPri] = { 255, 200 },
|
||||
[SchemeItemMarked] = { 255, 200 },
|
||||
[SchemeMenu] = { 255, 200 },
|
||||
[SchemeInput] = { 255, 200 },
|
||||
[SchemePrompt] = { 255, 200 },
|
||||
[SchemeNormHighlight] = { 255, 200 },
|
||||
[SchemeSelHighlight] = { 255, 200 },
|
||||
[SchemeMode] = { 255, 200 },
|
||||
[SchemeCaret] = { 255, 200 },
|
||||
[SchemeNumber] = { 255, 200 },
|
||||
[SchemeBorder] = { 255, 200 },
|
||||
[SchemeCaps] = { 255, 200 },
|
||||
};
|
||||
|
||||
// colorscheme array
|
||||
static char *colors[][2] = {
|
||||
// fg bg
|
||||
[SchemeLArrow] = { col_larrowfg, col_larrowbg },
|
||||
[SchemeRArrow] = { col_rarrowfg, col_rarrowbg },
|
||||
[SchemeItemNorm1] = { col_itemnormfg, col_itemnormbg },
|
||||
[SchemeItemNorm2] = { col_itemnormfg2, col_itemnormbg2 },
|
||||
[SchemeItemSel] = { col_itemselfg, col_itemselbg },
|
||||
[SchemeItemNormPri] = { col_itemnormprifg, col_itemnormpribg },
|
||||
[SchemeItemSelPri] = { col_itemselprifg, col_itemselpribg },
|
||||
[SchemeItemMarked] = { col_itemmarkedfg, col_itemmarkedbg },
|
||||
[SchemeInput] = { col_inputfg, col_inputbg, },
|
||||
[SchemeMenu] = { NULL, col_menu },
|
||||
[SchemeCaps] = { col_capsfg, col_capsbg },
|
||||
[SchemePrompt] = { col_promptfg, col_promptbg },
|
||||
[SchemeNormHighlight] = { col_hlnormfg, col_hlnormbg },
|
||||
[SchemeSelHighlight] = { col_hlselfg, col_hlselbg },
|
||||
[SchemeCaret] = { col_caretfg, col_caretbg },
|
||||
[SchemeMode] = { col_modefg, col_modebg },
|
||||
[SchemeNumber] = { col_numfg, col_numbg },
|
||||
[SchemeBorder] = { NULL, col_border },
|
||||
};
|
||||
|
||||
// sgr color array, first 16 colors are defined in the config, the rest are 256 colors
|
||||
static char *textcolors[] = {
|
||||
col_sgr0,
|
||||
|
@ -304,3 +258,5 @@ static char *textcolors[] = {
|
|||
"#e4e4e4",
|
||||
"#eeeeee",
|
||||
};
|
||||
|
||||
static char *txtcols[256];
|
||||
|
|
|
@ -9,8 +9,6 @@ void conf_init(void) {
|
|||
char *home = NULL;
|
||||
const char *dest;
|
||||
|
||||
// don't load configuration
|
||||
if (loadconfig) {
|
||||
// get path for configuration file
|
||||
if (!argconf) {
|
||||
if (!(xdg_conf = getenv("XDG_CONFIG_HOME"))) {
|
||||
|
@ -42,23 +40,24 @@ void conf_init(void) {
|
|||
|
||||
// don't bother trying to load if it doesn't exist.
|
||||
if (access(cfgfile, F_OK) != 0) {
|
||||
return;
|
||||
loadconfig = 0;
|
||||
}
|
||||
|
||||
// init config
|
||||
config_t cfg;
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
// attempt to read config file to cfg
|
||||
if (loadconfig) {
|
||||
if (!config_read_file(&cfg, cfgfile)) {
|
||||
// invalid configuration, but let's try to read it anyway
|
||||
fprintf(stderr, "spmenu: Invalid configuration.\n");
|
||||
}
|
||||
}
|
||||
|
||||
// load options spmenu.window
|
||||
config_setting_t *window_setting = config_lookup(&cfg, "spmenu.window");
|
||||
if (window_setting != NULL) {
|
||||
if (window_setting != NULL && loadconfig) {
|
||||
// look up window entries
|
||||
for (unsigned int i = 0; i < config_setting_length(window_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(window_setting, i);
|
||||
|
@ -77,12 +76,13 @@ void conf_init(void) {
|
|||
config_setting_lookup_int(conf, "managed", &managed); // spmenu.window.managed
|
||||
config_setting_lookup_int(conf, "monitor", &mon); // spmenu.window.monitor
|
||||
config_setting_lookup_int(conf, "alpha", &alpha); // spmenu.window.alpha
|
||||
config_setting_lookup_int(conf, "protocol", &protocol); // spmenu.window.protocol
|
||||
}
|
||||
}
|
||||
|
||||
// load options spmenu.properties
|
||||
config_setting_t *prop_setting = config_lookup(&cfg, "spmenu.properties");
|
||||
if (prop_setting != NULL) {
|
||||
if (prop_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(prop_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(prop_setting, i);
|
||||
|
||||
|
@ -96,7 +96,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.powerline
|
||||
config_setting_t *pwl_setting = config_lookup(&cfg, "spmenu.powerline");
|
||||
if (pwl_setting != NULL) {
|
||||
if (pwl_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(pwl_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(pwl_setting, i);
|
||||
|
||||
|
@ -114,7 +114,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.center
|
||||
config_setting_t *center_setting = config_lookup(&cfg, "spmenu.center");
|
||||
if (center_setting != NULL) {
|
||||
if (center_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(center_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(center_setting, i);
|
||||
|
||||
|
@ -124,7 +124,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.text
|
||||
config_setting_t *text_setting = config_lookup(&cfg, "spmenu.text");
|
||||
if (text_setting != NULL) {
|
||||
if (text_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(text_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(text_setting, i);
|
||||
|
||||
|
@ -162,7 +162,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.alpha
|
||||
config_setting_t *alpha_setting = config_lookup(&cfg, "spmenu.alpha");
|
||||
if (alpha_setting != NULL) {
|
||||
if (alpha_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(alpha_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(alpha_setting, i);
|
||||
|
||||
|
@ -226,131 +226,131 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.color
|
||||
config_setting_t *color_setting = config_lookup(&cfg, "spmenu.color");
|
||||
if (color_setting != NULL) {
|
||||
if (color_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(color_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(color_setting, i);
|
||||
|
||||
// items
|
||||
if (config_setting_lookup_string(conf, "itemnormfg", &dest))
|
||||
strcpy(colors[SchemeItemNorm1][ColFg], strdup(dest));
|
||||
strcpy(col_itemnormfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormbg", &dest))
|
||||
strcpy(colors[SchemeItemNorm1][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormfg2", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColFg], strdup(dest));
|
||||
strcpy(col_itemnormfg2, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemnormfg", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormfg2, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormbg2", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormbg2, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemnormbg", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormbg2, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselfg", &dest))
|
||||
strcpy(colors[SchemeItemSel][ColFg], strdup(dest));
|
||||
strcpy(col_itemselfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselbg", &dest))
|
||||
strcpy(colors[SchemeItemSel][ColBg], strdup(dest));
|
||||
strcpy(col_itemselbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemmarkedfg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColFg], strdup(dest));
|
||||
strcpy(col_itemmarkedfg, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemselfg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColFg], strdup(dest));
|
||||
strcpy(col_itemmarkedfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemmarkedbg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColBg], strdup(dest));
|
||||
strcpy(col_itemmarkedbg, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemselbg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColBg], strdup(dest));
|
||||
strcpy(col_itemmarkedbg, strdup(dest));
|
||||
|
||||
// items with priority
|
||||
if (config_setting_lookup_string(conf, "itemnormprifg", &dest))
|
||||
strcpy(colors[SchemeItemNormPri][ColFg], strdup(dest));
|
||||
strcpy(col_itemnormprifg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormpribg", &dest))
|
||||
strcpy(colors[SchemeItemNormPri][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormpribg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselprifg", &dest))
|
||||
strcpy(colors[SchemeItemSelPri][ColFg], strdup(dest));
|
||||
strcpy(col_itemselprifg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselpribg", &dest))
|
||||
strcpy(colors[SchemeItemSelPri][ColBg], strdup(dest));
|
||||
strcpy(col_itemselpribg, strdup(dest));
|
||||
|
||||
// input
|
||||
if (config_setting_lookup_string(conf, "inputfg", &dest))
|
||||
strcpy(colors[SchemeInput][ColFg], strdup(dest));
|
||||
strcpy(col_inputfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "inputbg", &dest))
|
||||
strcpy(colors[SchemeInput][ColBg], strdup(dest));
|
||||
strcpy(col_inputbg, strdup(dest));
|
||||
|
||||
// menu
|
||||
if (config_setting_lookup_string(conf, "menu", &dest))
|
||||
strcpy(colors[SchemeMenu][ColBg], strdup(dest));
|
||||
strcpy(col_menu, strdup(dest));
|
||||
|
||||
// prompt
|
||||
if (config_setting_lookup_string(conf, "promptfg", &dest))
|
||||
strcpy(colors[SchemePrompt][ColFg], strdup(dest));
|
||||
strcpy(col_promptfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "promptbg", &dest))
|
||||
strcpy(colors[SchemePrompt][ColBg], strdup(dest));
|
||||
strcpy(col_promptbg, strdup(dest));
|
||||
|
||||
// arrows
|
||||
if (config_setting_lookup_string(conf, "larrowfg", &dest))
|
||||
strcpy(colors[SchemeLArrow][ColFg], strdup(dest));
|
||||
strcpy(col_larrowfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "larrowbg", &dest))
|
||||
strcpy(colors[SchemeLArrow][ColBg], strdup(dest));
|
||||
strcpy(col_larrowbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "rarrowfg", &dest))
|
||||
strcpy(colors[SchemeRArrow][ColFg], strdup(dest));
|
||||
strcpy(col_rarrowfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "rarrowbg", &dest))
|
||||
strcpy(colors[SchemeRArrow][ColBg], strdup(dest));
|
||||
strcpy(col_rarrowbg, strdup(dest));
|
||||
|
||||
// highlight
|
||||
if (config_setting_lookup_string(conf, "hlnormfg", &dest))
|
||||
strcpy(colors[SchemeNormHighlight][ColFg], strdup(dest));
|
||||
strcpy(col_hlnormfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "hlnormbg", &dest))
|
||||
strcpy(colors[SchemeNormHighlight][ColBg], strdup(dest));
|
||||
strcpy(col_hlnormbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "hlselfg", &dest))
|
||||
strcpy(colors[SchemeSelHighlight][ColFg], strdup(dest));
|
||||
strcpy(col_hlselfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "hlselbg", &dest))
|
||||
strcpy(colors[SchemeSelHighlight][ColBg], strdup(dest));
|
||||
strcpy(col_hlselbg, strdup(dest));
|
||||
|
||||
// number
|
||||
if (config_setting_lookup_string(conf, "numfg", &dest))
|
||||
strcpy(colors[SchemeNumber][ColFg], strdup(dest));
|
||||
strcpy(col_numfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "numbg", &dest))
|
||||
strcpy(colors[SchemeNumber][ColBg], strdup(dest));
|
||||
strcpy(col_numbg, strdup(dest));
|
||||
|
||||
// mode
|
||||
if (config_setting_lookup_string(conf, "modefg", &dest))
|
||||
strcpy(colors[SchemeMode][ColFg], strdup(dest));
|
||||
strcpy(col_modefg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "modebg", &dest))
|
||||
strcpy(colors[SchemeMode][ColBg], strdup(dest));
|
||||
strcpy(col_modebg, strdup(dest));
|
||||
|
||||
// caps
|
||||
if (config_setting_lookup_string(conf, "capsfg", &dest))
|
||||
strcpy(colors[SchemeCaps][ColFg], strdup(dest));
|
||||
strcpy(col_capsfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "capsbg", &dest))
|
||||
strcpy(colors[SchemeCaps][ColBg], strdup(dest));
|
||||
strcpy(col_capsbg, strdup(dest));
|
||||
|
||||
// border
|
||||
if (config_setting_lookup_string(conf, "border", &dest))
|
||||
strcpy(colors[SchemeBorder][ColBg], strdup(dest));
|
||||
strcpy(col_border, strdup(dest));
|
||||
|
||||
// caret
|
||||
if (config_setting_lookup_string(conf, "caretfg", &dest))
|
||||
strcpy(colors[SchemeCaret][ColFg], strdup(dest));
|
||||
strcpy(col_caretfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "caretbg", &dest))
|
||||
strcpy(colors[SchemeCaret][ColBg], strdup(dest));
|
||||
strcpy(col_caretbg, strdup(dest));
|
||||
|
||||
// sgr colors
|
||||
if (config_setting_lookup_string(conf, "sgr0", &dest))
|
||||
|
@ -394,7 +394,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.image
|
||||
config_setting_t *img_setting = config_lookup(&cfg, "spmenu.image");
|
||||
if (img_setting != NULL) {
|
||||
if (img_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(img_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(img_setting, i);
|
||||
|
||||
|
@ -412,7 +412,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.file
|
||||
config_setting_t *file_setting = config_lookup(&cfg, "spmenu.file");
|
||||
if (file_setting != NULL) {
|
||||
if (file_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(file_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(file_setting, i);
|
||||
|
||||
|
@ -426,7 +426,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.input
|
||||
config_setting_t *input_setting = config_lookup(&cfg, "spmenu.input");
|
||||
if (input_setting != NULL) {
|
||||
if (input_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(input_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(input_setting, i);
|
||||
|
||||
|
@ -439,7 +439,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.output
|
||||
config_setting_t *output_setting = config_lookup(&cfg, "spmenu.output");
|
||||
if (output_setting != NULL) {
|
||||
if (output_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(output_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(output_setting, i);
|
||||
|
||||
|
@ -451,7 +451,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.mode
|
||||
config_setting_t *mode_setting = config_lookup(&cfg, "spmenu.mode");
|
||||
if (mode_setting != NULL) {
|
||||
if (mode_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(mode_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(mode_setting, i);
|
||||
|
||||
|
@ -468,7 +468,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.match
|
||||
config_setting_t *match_setting = config_lookup(&cfg, "spmenu.match");
|
||||
if (match_setting != NULL) {
|
||||
if (match_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(match_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(match_setting, i);
|
||||
|
||||
|
@ -478,7 +478,6 @@ void conf_init(void) {
|
|||
config_setting_lookup_int(conf, "fuzzy", &fuzzy); // spmenu.match.fuzzy
|
||||
config_setting_lookup_int(conf, "preselected", &preselected); // spmenu.match.preselected
|
||||
config_setting_lookup_int(conf, "mark", &mark); // spmenu.match.mark
|
||||
config_setting_lookup_int(conf, "accuratewidth", &accuratewidth); // spmenu.match.accuratewidth
|
||||
config_setting_lookup_string(conf, "delimiters", &dest); // spmenu.match.delimiters
|
||||
worddelimiters = strdup(dest);
|
||||
if (config_setting_lookup_string(conf, "listfile", &dest)) // spmenu.match.listfile
|
||||
|
@ -489,7 +488,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.line
|
||||
config_setting_t *line_setting = config_lookup(&cfg, "spmenu.line");
|
||||
if (line_setting != NULL) {
|
||||
if (line_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(line_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(line_setting, i);
|
||||
|
||||
|
@ -503,7 +502,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.history
|
||||
config_setting_t *hist_setting = config_lookup(&cfg, "spmenu.history");
|
||||
if (hist_setting != NULL) {
|
||||
if (hist_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(hist_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(hist_setting, i);
|
||||
|
||||
|
@ -515,7 +514,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.hide
|
||||
config_setting_t *hide_setting = config_lookup(&cfg, "spmenu.hide");
|
||||
if (hide_setting != NULL) {
|
||||
if (hide_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(hide_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(hide_setting, i);
|
||||
|
||||
|
@ -537,7 +536,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.pango
|
||||
config_setting_t *pango_setting = config_lookup(&cfg, "spmenu.pango");
|
||||
if (pango_setting != NULL) {
|
||||
if (pango_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(pango_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(pango_setting, i);
|
||||
|
||||
|
@ -557,7 +556,7 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.keys
|
||||
config_setting_t *key_setting = config_lookup(&cfg, "spmenu.keys");
|
||||
if (key_setting != NULL) {
|
||||
if (key_setting != NULL && loadconfig) {
|
||||
int nmode = 0;
|
||||
|
||||
for (unsigned int i = 0; i < config_setting_length(key_setting); ++i) {
|
||||
|
@ -572,8 +571,19 @@ void conf_init(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USEWAYLAND
|
||||
for (int j = 0; j < LENGTH(wml); j++) {
|
||||
if (!strcmp(wml[j].mod, strdup(dest))) {
|
||||
wl_ckeys[i].modifier = wml[j].modifier;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config_setting_lookup_int(conf, "mode", &nmode)) {
|
||||
ckeys[i].mode = nmode;
|
||||
#if USEWAYLAND
|
||||
wl_ckeys[i].mode = nmode;
|
||||
#endif
|
||||
}
|
||||
|
||||
config_setting_lookup_string(conf, "key", &dest);
|
||||
|
@ -584,11 +594,22 @@ void conf_init(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USEWAYLAND
|
||||
for (int j = 0; j < LENGTH(wkl); j++) {
|
||||
if (!strcmp(wkl[j].key, strdup(dest))) {
|
||||
wl_ckeys[i].keysym = wkl[j].keysym;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
config_setting_lookup_string(conf, "function", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(fl); j++) {
|
||||
if (!strcmp(fl[j].function, strdup(dest))) {
|
||||
ckeys[i].func = fl[j].func;
|
||||
#if USEWAYLAND
|
||||
wl_ckeys[i].func = fl[j].func;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -597,6 +618,9 @@ void conf_init(void) {
|
|||
for (int j = 0; j < LENGTH(al); j++) {
|
||||
if (!strcmp(al[j].argument, strdup(dest))) {
|
||||
ckeys[i].arg = al[j].arg;
|
||||
#if USEWAYLAND
|
||||
wl_ckeys[i].arg = al[j].arg;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,22 +630,18 @@ void conf_init(void) {
|
|||
|
||||
// load options spmenu.mouse
|
||||
config_setting_t *mouse_setting = config_lookup(&cfg, "spmenu.mouse");
|
||||
if (mouse_setting != NULL) {
|
||||
if (mouse_setting != NULL && loadconfig) {
|
||||
for (unsigned int i = 0; i < config_setting_length(mouse_setting); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(mouse_setting, i);
|
||||
|
||||
config_setting_lookup_string(conf, "click", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(ctp); j++) {
|
||||
if (!strcmp(ctp[j].tclick, strdup(dest))) {
|
||||
cbuttons[i].click = ctp[j].click;
|
||||
}
|
||||
}
|
||||
|
||||
// look up
|
||||
config_setting_lookup_string(conf, "modifier", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(ml); j++) {
|
||||
if (!strcmp(ml[j].mod, strdup(dest))) {
|
||||
cbuttons[i].mask = ml[j].modifier;
|
||||
#if USEWAYLAND
|
||||
wl_cbuttons[i].click = ctp[j].click;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,11 +653,22 @@ void conf_init(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USEWAYLAND
|
||||
for (int j = 0; j < LENGTH(w_btp); j++) {
|
||||
if (!strcmp(w_btp[j].click, strdup(dest))) {
|
||||
wl_cbuttons[i].button = w_btp[j].button;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
config_setting_lookup_string(conf, "function", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(fl); j++) {
|
||||
if (!strcmp(fl[j].function, strdup(dest))) {
|
||||
cbuttons[i].func = fl[j].func;
|
||||
#if USEWAYLAND
|
||||
wl_cbuttons[i].func = fl[j].func;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,6 +677,9 @@ void conf_init(void) {
|
|||
for (int j = 0; j < LENGTH(al); j++) {
|
||||
if (!strcmp(al[j].argument, strdup(dest))) {
|
||||
cbuttons[i].arg = al[j].arg;
|
||||
#if USEWAYLAND
|
||||
wl_cbuttons[i].arg = al[j].arg;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,14 +689,12 @@ void conf_init(void) {
|
|||
|
||||
// we're done with this config
|
||||
config_destroy(&cfg);
|
||||
}
|
||||
|
||||
// load the theme now
|
||||
if (loadtheme) {
|
||||
theme_load();
|
||||
}
|
||||
|
||||
if (loadbinds) {
|
||||
if (!argbinds) {
|
||||
if (!(xdg_conf = getenv("XDG_CONFIG_HOME"))) {
|
||||
home = getenv("HOME");
|
||||
|
@ -705,10 +737,13 @@ void conf_init(void) {
|
|||
|
||||
// load options binds.keys
|
||||
config_setting_t *key_bind = config_lookup(&bind, "bind.keys");
|
||||
if (key_bind != NULL) {
|
||||
if (key_bind != NULL && loadbinds) {
|
||||
int nmode = 0;
|
||||
|
||||
memset(ckeys, '\0', LENGTH(ckeys)-1);
|
||||
#if USEWAYLAND
|
||||
memset(wl_ckeys, '\0', LENGTH(wl_ckeys)-1);
|
||||
#endif
|
||||
for (unsigned int i = 0; i < config_setting_length(key_bind); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(key_bind, i);
|
||||
|
||||
|
@ -721,8 +756,19 @@ void conf_init(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USEWAYLAND
|
||||
for (int j = 0; j < LENGTH(wml); j++) {
|
||||
if (!strcmp(wml[j].mod, strdup(dest))) {
|
||||
wl_ckeys[i].modifier = wml[j].modifier;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (config_setting_lookup_int(conf, "mode", &nmode)) {
|
||||
ckeys[i].mode = nmode;
|
||||
#if USEWAYLAND
|
||||
wl_ckeys[i].mode = nmode;
|
||||
#endif
|
||||
}
|
||||
|
||||
config_setting_lookup_string(conf, "key", &dest);
|
||||
|
@ -733,11 +779,22 @@ void conf_init(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USEWAYLAND
|
||||
for (int j = 0; j < LENGTH(wkl); j++) {
|
||||
if (!strcmp(wkl[j].key, strdup(dest))) {
|
||||
wl_ckeys[i].keysym = wkl[j].keysym;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
config_setting_lookup_string(conf, "function", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(fl); j++) {
|
||||
if (!strcmp(fl[j].function, strdup(dest))) {
|
||||
ckeys[i].func = fl[j].func;
|
||||
#if USEWAYLAND
|
||||
wl_ckeys[i].func = fl[j].func;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,6 +803,9 @@ void conf_init(void) {
|
|||
for (int j = 0; j < LENGTH(al); j++) {
|
||||
if (!strcmp(al[j].argument, strdup(dest))) {
|
||||
ckeys[i].arg = al[j].arg;
|
||||
#if USEWAYLAND
|
||||
wl_ckeys[i].arg = al[j].arg;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -755,26 +815,19 @@ void conf_init(void) {
|
|||
|
||||
// load options binds.mouse
|
||||
config_setting_t *mouse_bind = config_lookup(&bind, "bind.mouse");
|
||||
if (mouse_bind != NULL) {
|
||||
if (mouse_bind != NULL && loadbinds) {
|
||||
memset(cbuttons, '\0', LENGTH(cbuttons)-1);
|
||||
for (unsigned int i = 0; i < config_setting_length(mouse_bind); ++i) {
|
||||
config_setting_t *conf = config_setting_get_elem(mouse_bind, i);
|
||||
|
||||
// look up
|
||||
config_setting_lookup_string(conf, "click", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(ctp); j++) {
|
||||
if (!strcmp(ctp[j].tclick, strdup(dest))) {
|
||||
cbuttons[i].click = ctp[j].click;
|
||||
}
|
||||
}
|
||||
|
||||
// look up
|
||||
config_setting_lookup_string(conf, "modifier", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(ml); j++) {
|
||||
if (!strcmp(ml[j].mod, strdup(dest))) {
|
||||
cbuttons[i].mask = ml[j].modifier;
|
||||
#if USEWAYLAND
|
||||
wl_cbuttons[i].click = ctp[j].click;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -786,11 +839,22 @@ void conf_init(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#if USEWAYLAND
|
||||
for (int j = 0; j < LENGTH(w_btp); j++) {
|
||||
if (!strcmp(w_btp[j].click, strdup(dest))) {
|
||||
wl_cbuttons[i].button = w_btp[j].button;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
config_setting_lookup_string(conf, "function", &dest);
|
||||
|
||||
for (int j = 0; j < LENGTH(fl); j++) {
|
||||
if (!strcmp(fl[j].function, strdup(dest))) {
|
||||
cbuttons[i].func = fl[j].func;
|
||||
#if USEWAYLAND
|
||||
wl_cbuttons[i].func = fl[j].func;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,6 +863,9 @@ void conf_init(void) {
|
|||
for (int j = 0; j < LENGTH(al); j++) {
|
||||
if (!strcmp(al[j].argument, strdup(dest))) {
|
||||
cbuttons[i].arg = al[j].arg;
|
||||
#if USEWAYLAND
|
||||
wl_cbuttons[i].arg = al[j].arg;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,7 +875,6 @@ void conf_init(void) {
|
|||
|
||||
// finally done
|
||||
config_destroy(&bind);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,11 +6,25 @@ typedef struct {
|
|||
KeySym keysym;
|
||||
} KeyList;
|
||||
|
||||
#if USEWAYLAND
|
||||
typedef struct {
|
||||
char *key;
|
||||
xkb_keysym_t keysym;
|
||||
} WlKeyList;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *mod;
|
||||
unsigned int modifier;
|
||||
} ModList;
|
||||
|
||||
#if USEWAYLAND
|
||||
typedef struct {
|
||||
char *mod;
|
||||
char *modifier;
|
||||
} WlModList;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *argument;
|
||||
Arg arg;
|
||||
|
@ -396,6 +410,25 @@ static ModList ml[] = {
|
|||
{ "0", 0 },
|
||||
};
|
||||
|
||||
#if USEWAYLAND
|
||||
static WlModList wml[] = {
|
||||
{ "Ctrl+Shift", WL_CtrlShift },
|
||||
{ "Ctrl+Shift+Super", WL_CtrlShiftSuper },
|
||||
{ "Ctrl+Super", WL_CtrlSuper },
|
||||
{ "Ctrl+Alt", WL_CtrlAlt },
|
||||
{ "Ctrl+Alt+Shift", WL_CtrlAltShift },
|
||||
{ "Ctrl+Alt+Shift+Super", WL_CtrlAltShiftSuper },
|
||||
{ "Ctrl+Alt+Super", WL_CtrlAltSuper },
|
||||
{ "Alt+Shift", WL_AltShift },
|
||||
{ "Shift", WL_Shift },
|
||||
{ "Ctrl", WL_Ctrl },
|
||||
{ "Alt", WL_Alt },
|
||||
{ "Super", WL_Super },
|
||||
{ "None", WL_None },
|
||||
{ "0", WL_None },
|
||||
};
|
||||
#endif
|
||||
|
||||
// list of keys that can be used in the config file
|
||||
// expand this array if you want more
|
||||
static KeyList kl[] = {
|
||||
|
@ -500,11 +533,124 @@ static KeyList kl[] = {
|
|||
{ "Prior", XK_Prior },
|
||||
};
|
||||
|
||||
// list of keys that can be used in the config file
|
||||
// expand this array if you want more
|
||||
#if USEWAYLAND
|
||||
static WlKeyList wkl[] = {
|
||||
{ "None", 0 },
|
||||
{ "Space", XKB_KEY_space },
|
||||
{ "Enter", XKB_KEY_Return },
|
||||
{ "Tab", XKB_KEY_Tab },
|
||||
{ "a", XKB_KEY_a },
|
||||
{ "b", XKB_KEY_b },
|
||||
{ "c", XKB_KEY_c },
|
||||
{ "d", XKB_KEY_d },
|
||||
{ "e", XKB_KEY_e },
|
||||
{ "f", XKB_KEY_f },
|
||||
{ "g", XKB_KEY_g },
|
||||
{ "h", XKB_KEY_h },
|
||||
{ "i", XKB_KEY_i },
|
||||
{ "j", XKB_KEY_j },
|
||||
{ "k", XKB_KEY_k },
|
||||
{ "l", XKB_KEY_l },
|
||||
{ "m", XKB_KEY_m },
|
||||
{ "n", XKB_KEY_n },
|
||||
{ "o", XKB_KEY_o },
|
||||
{ "p", XKB_KEY_p },
|
||||
{ "q", XKB_KEY_q },
|
||||
{ "r", XKB_KEY_r },
|
||||
{ "s", XKB_KEY_s },
|
||||
{ "t", XKB_KEY_t },
|
||||
{ "u", XKB_KEY_u },
|
||||
{ "v", XKB_KEY_v },
|
||||
{ "w", XKB_KEY_w },
|
||||
{ "x", XKB_KEY_x },
|
||||
{ "y", XKB_KEY_y },
|
||||
{ "z", XKB_KEY_z },
|
||||
{ "0", XKB_KEY_0 },
|
||||
{ "1", XKB_KEY_1 },
|
||||
{ "2", XKB_KEY_2 },
|
||||
{ "3", XKB_KEY_3 },
|
||||
{ "4", XKB_KEY_4 },
|
||||
{ "5", XKB_KEY_5 },
|
||||
{ "6", XKB_KEY_6 },
|
||||
{ "7", XKB_KEY_7 },
|
||||
{ "8", XKB_KEY_8 },
|
||||
{ "9", XKB_KEY_9 },
|
||||
{ "!", XKB_KEY_exclam },
|
||||
{ "\"", XKB_KEY_quotedbl },
|
||||
{ "#", XKB_KEY_numbersign },
|
||||
{ "$", XKB_KEY_dollar },
|
||||
{ "%", XKB_KEY_percent },
|
||||
{ "&", XKB_KEY_ampersand },
|
||||
{ "'", XKB_KEY_apostrophe },
|
||||
{ "(", XKB_KEY_parenleft },
|
||||
{ ")", XKB_KEY_parenright },
|
||||
{ "*", XKB_KEY_asterisk },
|
||||
{ "+", XKB_KEY_plus },
|
||||
{ ",", XKB_KEY_comma },
|
||||
{ "-", XKB_KEY_minus },
|
||||
{ ".", XKB_KEY_period },
|
||||
{ "/", XKB_KEY_slash },
|
||||
{ ":", XKB_KEY_colon },
|
||||
{ ";", XKB_KEY_semicolon },
|
||||
{ "<", XKB_KEY_less },
|
||||
{ "=", XKB_KEY_equal },
|
||||
{ ">", XKB_KEY_greater },
|
||||
{ "?", XKB_KEY_question },
|
||||
{ "@", XKB_KEY_at },
|
||||
{ "[", XKB_KEY_bracketleft },
|
||||
{ "\\", XKB_KEY_backslash },
|
||||
{ "]", XKB_KEY_bracketright },
|
||||
{ "_", XKB_KEY_underscore },
|
||||
{ "grave", XKB_KEY_grave },
|
||||
{ "{", XKB_KEY_braceleft },
|
||||
{ "bar", XKB_KEY_bar },
|
||||
{ "}", XKB_KEY_braceright },
|
||||
{ "~", XKB_KEY_asciitilde },
|
||||
{ "F1", XKB_KEY_F1 },
|
||||
{ "F2", XKB_KEY_F2 },
|
||||
{ "F3", XKB_KEY_F3 },
|
||||
{ "F4", XKB_KEY_F4 },
|
||||
{ "F5", XKB_KEY_F5 },
|
||||
{ "F6", XKB_KEY_F6 },
|
||||
{ "F7", XKB_KEY_F7 },
|
||||
{ "F8", XKB_KEY_F8 },
|
||||
{ "F9", XKB_KEY_F9 },
|
||||
{ "F10", XKB_KEY_F10 },
|
||||
{ "F11", XKB_KEY_F11 },
|
||||
{ "F12", XKB_KEY_F12 },
|
||||
{ "PageUp", XKB_KEY_Page_Up },
|
||||
{ "PageDown", XKB_KEY_Page_Down },
|
||||
{ "Home", XKB_KEY_Home },
|
||||
{ "End", XKB_KEY_End },
|
||||
{ "Delete", XKB_KEY_Delete },
|
||||
{ "PrintScr", XKB_KEY_Print },
|
||||
{ "Esc", XKB_KEY_Escape },
|
||||
{ "Pause", XKB_KEY_Pause },
|
||||
{ "ScrollLock", XKB_KEY_Scroll_Lock },
|
||||
{ "Backspace", XKB_KEY_BackSpace },
|
||||
{ "Up", XKB_KEY_Up },
|
||||
{ "Down", XKB_KEY_Down },
|
||||
{ "Left", XKB_KEY_Left },
|
||||
{ "Right", XKB_KEY_Right },
|
||||
{ "Next", XKB_KEY_Next },
|
||||
{ "Prior", XKB_KEY_Prior },
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *click;
|
||||
unsigned int button;
|
||||
} ButtonType;
|
||||
|
||||
#if USEWAYLAND
|
||||
typedef struct {
|
||||
char *click;
|
||||
unsigned int button;
|
||||
} WlButtonType;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *tclick;
|
||||
unsigned int click;
|
||||
|
@ -518,6 +664,14 @@ static ButtonType btp[] = {
|
|||
{ "Scroll Down", Button5 },
|
||||
};
|
||||
|
||||
#if USEWAYLAND
|
||||
static WlButtonType w_btp[] = {
|
||||
{ "Left Click", WL_Left },
|
||||
{ "Middle Click", WL_Middle },
|
||||
{ "Right Click", WL_Right },
|
||||
};
|
||||
#endif
|
||||
|
||||
static ClickType ctp[] = {
|
||||
{ "ClickWindow", ClickWindow },
|
||||
{ "ClickPrompt", ClickPrompt },
|
||||
|
@ -529,18 +683,6 @@ static ClickType ctp[] = {
|
|||
{ "ClickNumber", ClickNumber },
|
||||
{ "ClickCaps", ClickCaps },
|
||||
{ "ClickMode", ClickMode },
|
||||
|
||||
// compatibility
|
||||
{ "clickwindow", ClickWindow },
|
||||
{ "clickprompt", ClickPrompt },
|
||||
{ "clickinput", ClickInput },
|
||||
{ "clicklarrow", ClickLArrow },
|
||||
{ "clickitem", ClickItem },
|
||||
{ "clickselitem", ClickSelItem },
|
||||
{ "clickrarrow", ClickRArrow },
|
||||
{ "clicknumber", ClickNumber },
|
||||
{ "clickcaps", ClickCaps },
|
||||
{ "clickmode", ClickMode },
|
||||
};
|
||||
|
||||
static void conf_init(void);
|
||||
|
|
215
libs/draw.c
215
libs/draw.c
|
@ -11,9 +11,6 @@ void drawhighlights(struct item *item, int x, int y, int w, int p, const char *i
|
|||
|
||||
if (!(strlen(itemtext) && strlen(text))) return;
|
||||
|
||||
drw_setscheme(drw, scheme[item == sel
|
||||
? SchemeSelHighlight
|
||||
: SchemeNormHighlight]);
|
||||
for (i = 0, highlight = itemtext; *highlight && text[i];) {
|
||||
if (((fuzzy && !fstrncmp(&(*highlight), &text[i], 1)) || (!fuzzy && *highlight == text[i]))) {
|
||||
c = *highlight;
|
||||
|
@ -29,7 +26,11 @@ void drawhighlights(struct item *item, int x, int y, int w, int p, const char *i
|
|||
x + indent + (p),
|
||||
y,
|
||||
MIN(w - indent - lrpad, TEXTW(highlight) - lrpad),
|
||||
bh, 0, highlight, 0, pango_highlight ? True : False);
|
||||
bh, 0, highlight, 0, pango_highlight ? True : False,
|
||||
item == sel ? col_hlselfg : col_hlnormfg,
|
||||
item == sel ? col_hlselbg : col_hlnormbg,
|
||||
item == sel ? alpha_hlselfg : alpha_hlnormfg,
|
||||
item == sel ? alpha_hlselbg : alpha_hlnormbg);
|
||||
highlight[1] = c;
|
||||
i++;
|
||||
}
|
||||
|
@ -39,7 +40,6 @@ void drawhighlights(struct item *item, int x, int y, int w, int p, const char *i
|
|||
|
||||
int drawitemtext(struct item *item, int x, int y, int w) {
|
||||
char buffer[MAXITEMLENGTH]; // buffer containing item text
|
||||
Clr scm[2]; // color scheme
|
||||
int leftpadding = lrpad / 2; // padding
|
||||
int wr, rd; // character
|
||||
int fg = 7; // foreground
|
||||
|
@ -48,31 +48,54 @@ int drawitemtext(struct item *item, int x, int y, int w) {
|
|||
int ignore = 0; // ignore colors
|
||||
int selitem = 0;
|
||||
int priitem = 0;
|
||||
char *bgcol;
|
||||
char *fgcol;
|
||||
int bga;
|
||||
int fga;
|
||||
|
||||
// memcpy the correct scheme
|
||||
if (item == sel) {
|
||||
memcpy(scm, scheme[SchemeItemSel], sizeof(scm));
|
||||
selitem = 1;
|
||||
bgcol = col_itemselbg;
|
||||
fgcol = col_itemselfg;
|
||||
bga = alpha_itemselbg;
|
||||
fga = alpha_itemselfg;
|
||||
|
||||
if (item->hp) {
|
||||
memcpy(scm, scheme[SchemeItemSelPri], sizeof(scm));
|
||||
priitem = 1;
|
||||
bgcol = col_itemselpribg;
|
||||
fgcol = col_itemselprifg;
|
||||
|
||||
fga = alpha_itemselprifg;
|
||||
bga = alpha_itemselpribg;
|
||||
}
|
||||
} else {
|
||||
if (itemn) {
|
||||
memcpy(scm, scheme[SchemeItemNorm2], sizeof(scm));
|
||||
bgcol = col_itemnormbg2;
|
||||
fgcol = col_itemnormfg2;
|
||||
fga = alpha_itemnormfg2;
|
||||
bga = alpha_itemnormbg2;
|
||||
} else {
|
||||
memcpy(scm, scheme[SchemeItemNorm1], sizeof(scm));
|
||||
bgcol = col_itemnormbg;
|
||||
fgcol = col_itemnormfg;
|
||||
fga = alpha_itemnormfg;
|
||||
bga = alpha_itemnormbg;
|
||||
}
|
||||
|
||||
if (item->hp) {
|
||||
memcpy(scm, scheme[SchemeItemNormPri], sizeof(scm));
|
||||
priitem = 1;
|
||||
bgcol = col_itemnormpribg;
|
||||
fgcol = col_itemnormprifg;
|
||||
fga = alpha_itemnormprifg;
|
||||
bga = alpha_itemnormpribg;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_selected(item->index)) {
|
||||
memcpy(scm, scheme[SchemeItemMarked], sizeof(scm));
|
||||
bgcol = col_itemmarkedbg;
|
||||
fgcol = col_itemmarkedfg;
|
||||
fga = alpha_itemmarkedfg;
|
||||
bga = alpha_itemmarkedbg;
|
||||
}
|
||||
|
||||
// apply extra padding
|
||||
|
@ -85,9 +108,12 @@ int drawitemtext(struct item *item, int x, int y, int w) {
|
|||
}
|
||||
|
||||
// don't color
|
||||
if (!coloritems) memcpy(scm, scheme[SchemeItemNorm1], sizeof(scm));
|
||||
|
||||
drw_setscheme(drw, scm); // set scheme
|
||||
if (!coloritems) {
|
||||
bgcol = itemn ? col_itemnormbg2 : col_itemnormbg;
|
||||
fgcol = itemn ? col_itemnormfg2 : col_itemnormfg;
|
||||
bga = itemn ? alpha_itemnormbg2 : alpha_itemnormbg;
|
||||
fga = itemn ? alpha_itemnormfg2 : alpha_itemnormfg;
|
||||
}
|
||||
|
||||
// parse item text
|
||||
for (wr = 0, rd = 0; item->text[rd]; rd++) {
|
||||
|
@ -101,7 +127,7 @@ int drawitemtext(struct item *item, int x, int y, int w) {
|
|||
}
|
||||
|
||||
apply_fribidi(buffer);
|
||||
drw_text(drw, x, y, MIN(w, TEXTW(buffer) - lrpad) + leftpadding, bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False);
|
||||
drw_text(drw, x, y, MIN(w, TEXTW(buffer) - lrpad) + leftpadding, bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
|
||||
drawhighlights(item, x, y, MIN(w, TEXTW(buffer) - lrpad) + leftpadding, leftpadding, isrtl ? fribidi_text : buffer);
|
||||
|
||||
// position and width
|
||||
|
@ -113,7 +139,7 @@ int drawitemtext(struct item *item, int x, int y, int w) {
|
|||
|
||||
char *character = item->text + rd + 1; // current character
|
||||
|
||||
// parse hex colors in scm, m is always the last character
|
||||
// parse hex colors, m is always the last character
|
||||
while (*character != 'm') {
|
||||
unsigned nextchar = strtoul(character + 1, &character, 10);
|
||||
if (ignore)
|
||||
|
@ -123,62 +149,91 @@ int drawitemtext(struct item *item, int x, int y, int w) {
|
|||
bgfg <<= 1;
|
||||
continue;
|
||||
}
|
||||
if (bgfg == 4)
|
||||
scm[0] = textclrs[fg = nextchar];
|
||||
else if (bgfg == 6)
|
||||
scm[1] = textclrs[bg = nextchar];
|
||||
ignore = 1;
|
||||
if (bgfg == 4) {
|
||||
fgcol = txtcols[fg = nextchar];
|
||||
} else if (bgfg == 6) {
|
||||
bgcol = txtcols[bg = nextchar];
|
||||
}
|
||||
|
||||
ignore = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nextchar == 1) {
|
||||
fg |= 8;
|
||||
scm[0] = textclrs[fg];
|
||||
fgcol = txtcols[fg];
|
||||
} else if (nextchar == 22) {
|
||||
fg &= ~8;
|
||||
scm[0] = textclrs[fg];
|
||||
fgcol = txtcols[fg];
|
||||
} else if (nextchar == 38) {
|
||||
bgfg = 2;
|
||||
} else if (nextchar >= 30 && nextchar <= 37) {
|
||||
fg = nextchar % 10 | (fg & 8);
|
||||
scm[0] = textclrs[fg];
|
||||
fgcol = txtcols[fg];
|
||||
} else if (nextchar >= 40 && nextchar <= 47) {
|
||||
bg = nextchar % 10;
|
||||
scm[1] = textclrs[bg];
|
||||
bgcol = txtcols[bg];
|
||||
} else if (nextchar == 48) {
|
||||
bgfg = 3;
|
||||
} else if (nextchar == 0) {
|
||||
// memcpy the correct scheme
|
||||
if (item == sel) {
|
||||
memcpy(scm, scheme[SchemeItemSel], sizeof(scm));
|
||||
selitem = 1;
|
||||
bgcol = col_itemselbg;
|
||||
fgcol = col_itemselfg;
|
||||
bga = alpha_itemselbg;
|
||||
fga = alpha_itemselfg;
|
||||
|
||||
if (item->hp)
|
||||
memcpy(scm, scheme[SchemeItemSelPri], sizeof(scm));
|
||||
if (item->hp) {
|
||||
priitem = 1;
|
||||
bgcol = col_itemselpribg;
|
||||
fgcol = col_itemselprifg;
|
||||
|
||||
fga = alpha_itemselprifg;
|
||||
bga = alpha_itemselpribg;
|
||||
}
|
||||
} else {
|
||||
if (itemn) {
|
||||
memcpy(scm, scheme[SchemeItemNorm2], sizeof(scm));
|
||||
bgcol = col_itemnormbg2;
|
||||
fgcol = col_itemnormfg2;
|
||||
fga = alpha_itemnormfg2;
|
||||
bga = alpha_itemnormbg2;
|
||||
} else {
|
||||
memcpy(scm, scheme[SchemeItemNorm1], sizeof(scm));
|
||||
bgcol = col_itemnormbg;
|
||||
fgcol = col_itemnormfg;
|
||||
fga = alpha_itemnormfg;
|
||||
bga = alpha_itemnormbg;
|
||||
}
|
||||
|
||||
if (item->hp)
|
||||
memcpy(scm, scheme[SchemeItemNormPri], sizeof(scm));
|
||||
if (item->hp) {
|
||||
priitem = 1;
|
||||
bgcol = col_itemnormpribg;
|
||||
fgcol = col_itemnormprifg;
|
||||
fga = alpha_itemnormprifg;
|
||||
bga = alpha_itemnormpribg;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_selected(item->index)) {
|
||||
memcpy(scm, scheme[SchemeItemMarked], sizeof(scm));
|
||||
bgcol = col_itemmarkedbg;
|
||||
fgcol = col_itemmarkedfg;
|
||||
fga = alpha_itemmarkedfg;
|
||||
bga = alpha_itemmarkedbg;
|
||||
}
|
||||
|
||||
// don't color
|
||||
if (!coloritems) memcpy(scm, scheme[SchemeItemNorm1], sizeof(scm));
|
||||
if (!coloritems) {
|
||||
bgcol = itemn ? col_itemnormbg2 : col_itemnormbg;
|
||||
fgcol = itemn ? col_itemnormfg2 : col_itemnormfg;
|
||||
bga = itemn ? alpha_itemnormbg2 : alpha_itemnormbg;
|
||||
fga = itemn ? alpha_itemnormfg2 : alpha_itemnormfg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rd += alen + 2;
|
||||
wr = 0;
|
||||
|
||||
drw_setscheme(drw, scm); // set scheme
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +245,7 @@ int drawitemtext(struct item *item, int x, int y, int w) {
|
|||
|
||||
// now draw any non-colored text
|
||||
apply_fribidi(buffer);
|
||||
int r = drw_text(drw, x, y, w, bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False);
|
||||
int r = drw_text(drw, x, y, w, bh, leftpadding, isrtl ? fribidi_text : buffer, 0, pango_item ? True : False, fgcol, bgcol, fga, bga);
|
||||
if (!hidehighlight) drawhighlights(item, x, y, w, leftpadding, buffer);
|
||||
|
||||
// copy current buffer to item->clntext instead of item->text, this way SGR sequences aren't drawn
|
||||
|
@ -231,7 +286,7 @@ int drawitem(int x, int y, int w) {
|
|||
|
||||
// draw image first
|
||||
#if USEIMAGE
|
||||
if (!hideimage && longestedge != 0) {
|
||||
if (!hideimage && longestedge != 0 && !protocol) { // TODO: wayland image support
|
||||
rx = ox;
|
||||
rx += MAX((imagegaps * 2) + imagewidth + menumarginh, indentitems ? x : 0);
|
||||
} else
|
||||
|
@ -301,14 +356,10 @@ int drawitem(int x, int y, int w) {
|
|||
|
||||
int drawprompt(int x, int y, int w) {
|
||||
if (prompt && *prompt && !hideprompt) {
|
||||
drw_setscheme(drw, scheme[SchemePrompt]);
|
||||
|
||||
x = drw_text(drw, x, y, w, bh, lrpad / 2, prompt, 0, pango_prompt ? True : False);
|
||||
x = drw_text(drw, x, y, w, bh, lrpad / 2, prompt, 0, pango_prompt ? True : False, col_promptfg, col_promptbg, alpha_promptfg, alpha_promptbg);
|
||||
|
||||
if (!hidepowerline && powerlineprompt) {
|
||||
drw_settrans(drw, scheme[SchemePrompt], scheme[SchemeMenu]);
|
||||
drw_arrow(drw, x, y, plw, bh, 1, promptpwlstyle);
|
||||
|
||||
drw_arrow(drw, x, y, plw, bh, 1, promptpwlstyle, col_menu, col_promptbg, alpha_menu, alpha_promptbg);
|
||||
x += plw;
|
||||
}
|
||||
}
|
||||
|
@ -321,9 +372,6 @@ int drawinput(int x, int y, int w) {
|
|||
unsigned int curpos = 0;
|
||||
int fh = drw->font->h;
|
||||
|
||||
// draw input
|
||||
drw_setscheme(drw, scheme[SchemeInput]);
|
||||
|
||||
if (passwd) {
|
||||
censort = ecalloc(1, sizeof(text));
|
||||
|
||||
|
@ -331,21 +379,20 @@ int drawinput(int x, int y, int w) {
|
|||
memcpy(&censort[i], password, strlen(text));
|
||||
|
||||
apply_fribidi(censort);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2, isrtl ? fribidi_text : censort, 0, pango_password ? True : False);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2, isrtl ? fribidi_text : censort, 0, pango_password ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg);
|
||||
|
||||
curpos = TEXTW(censort) - TEXTW(&text[cursor]);
|
||||
|
||||
free(censort);
|
||||
} else if (!passwd) {
|
||||
apply_fribidi(text);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2, isrtl ? fribidi_text : text, 0, pango_input ? True : False);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2, isrtl ? fribidi_text : text, 0, pango_input ? True : False, col_inputfg, col_inputbg, alpha_inputfg, alpha_inputbg);
|
||||
|
||||
curpos = TEXTW(text) - TEXTW(&text[cursor]);
|
||||
}
|
||||
|
||||
if ((curpos += lrpad / 2 - 1) < w && !hidecaret && cursorstate) {
|
||||
drw_setscheme(drw, scheme[SchemeCaret]);
|
||||
drw_rect(drw, x + curpos, 2 + (bh - fh) / 2 + y, 2, fh - 4, 1, 0);
|
||||
drw_rect(drw, x + curpos, 2 + (bh - fh) / 2 + y, 2, fh - 4, 1, 0, col_caretfg, col_caretbg, alpha_caretfg, alpha_caretbg);
|
||||
}
|
||||
|
||||
return x;
|
||||
|
@ -355,8 +402,7 @@ int drawlarrow(int x, int y, int w) {
|
|||
if (hidelarrow) return x;
|
||||
|
||||
if (curr->left) { // draw left arrow
|
||||
drw_setscheme(drw, scheme[SchemeLArrow]);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2, leftarrow, 0, pango_leftarrow ? True : False);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2, leftarrow, 0, pango_leftarrow ? True : False, col_larrowfg, col_larrowbg, alpha_larrowfg, alpha_larrowbg);
|
||||
x += w;
|
||||
}
|
||||
|
||||
|
@ -367,8 +413,7 @@ int drawrarrow(int x, int y, int w) {
|
|||
if (hiderarrow) return x;
|
||||
|
||||
if (next) { // draw right arrow
|
||||
drw_setscheme(drw, scheme[SchemeRArrow]);
|
||||
drw_text(drw, mw - w, y, w, bh, lrpad / 2, rightarrow, 0, pango_rightarrow ? True : False);
|
||||
drw_text(drw, mw - w, y, w, bh, lrpad / 2, rightarrow, 0, pango_rightarrow ? True : False, col_rarrowfg, col_rarrowbg, alpha_rarrowfg, alpha_rarrowbg);
|
||||
x += w;
|
||||
}
|
||||
|
||||
|
@ -384,13 +429,11 @@ int drawnumber(int x, int y, int w) {
|
|||
powerlinewidth = plw / 2;
|
||||
}
|
||||
|
||||
drw_setscheme(drw, scheme[SchemeNumber]);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, numbers, 0, pango_numbers ? True : False);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, numbers, 0, pango_numbers ? True : False, col_numfg, col_numbg, alpha_numfg, alpha_numbg);
|
||||
|
||||
// draw powerline for match count
|
||||
if (!hidepowerline && powerlinecount) {
|
||||
drw_settrans(drw, scheme[SchemeNumber], scheme[SchemeMenu]);
|
||||
drw_arrow(drw, x, y, plw, bh, 0, matchcountpwlstyle);
|
||||
drw_arrow(drw, x, y, plw, bh, 0, matchcountpwlstyle, col_menu, col_numbg, alpha_menu, alpha_numbg);
|
||||
|
||||
x += plw;
|
||||
}
|
||||
|
@ -406,13 +449,13 @@ int drawmode(int x, int y, int w) {
|
|||
powerlinewidth = plw / 2;
|
||||
}
|
||||
|
||||
drw_setscheme(drw, scheme[SchemeMode]);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, modetext, 0, pango_mode ? True : False);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, modetext, 0, pango_mode ? True : False, col_modefg, col_modebg, alpha_modefg, alpha_modebg);
|
||||
|
||||
// draw powerline for match count
|
||||
if (!hidepowerline && powerlinemode) {
|
||||
drw_settrans(drw, scheme[SchemeMode], hidematchcount ? scheme[SchemeMenu] : scheme[SchemeNumber]);
|
||||
drw_arrow(drw, x, y, plw, bh, 0, modepwlstyle);
|
||||
drw_arrow(drw, x, y, plw, bh, 0, modepwlstyle,
|
||||
hidematchcount ? col_menu : col_numbg, col_modebg,
|
||||
hidematchcount ? alpha_menu : alpha_numbg, alpha_modebg);
|
||||
|
||||
x += plw;
|
||||
}
|
||||
|
@ -431,13 +474,13 @@ int drawcaps(int x, int y, int w) {
|
|||
powerlinewidth = plw / 2;
|
||||
}
|
||||
|
||||
drw_setscheme(drw, scheme[SchemeCaps]);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, capstext, 0, pango_caps ? True : False);
|
||||
drw_text(drw, x, y, w, bh, lrpad / 2 + powerlinewidth, capstext, 0, pango_caps ? True : False, col_capsfg, col_capsbg, alpha_capsfg, alpha_capsbg);
|
||||
|
||||
// draw powerline for caps lock indicator
|
||||
if (!hidepowerline && powerlinecaps) {
|
||||
drw_settrans(drw, scheme[SchemeCaps], hidemode ? hidematchcount ? scheme[SchemeMenu] : scheme[SchemeNumber] : scheme[SchemeMode]);
|
||||
drw_arrow(drw, x, y, plw, bh, 0, capspwlstyle);
|
||||
drw_arrow(drw, x, y, plw, bh, 0, capspwlstyle,
|
||||
hidemode ? hidematchcount ? col_menu : col_numbg : col_modebg, col_capsbg,
|
||||
hidemode ? hidematchcount ? alpha_menu : alpha_numbg : alpha_modebg, alpha_capsbg);
|
||||
|
||||
x += plw;
|
||||
}
|
||||
|
@ -447,12 +490,29 @@ int drawcaps(int x, int y, int w) {
|
|||
}
|
||||
|
||||
void drawmenu(void) {
|
||||
#if USEWAYLAND
|
||||
if (protocol) {
|
||||
readfile();
|
||||
drawmenu_layer();
|
||||
|
||||
wl_surface_set_buffer_scale(state.surface, 1);
|
||||
wl_surface_attach(state.surface, state.buffer, 0, 0);
|
||||
wl_surface_damage(state.surface, 0, 0, state.width, state.height);
|
||||
wl_surface_commit(state.surface);
|
||||
} else {
|
||||
drawmenu_layer();
|
||||
}
|
||||
#else
|
||||
drawmenu_layer();
|
||||
#endif
|
||||
}
|
||||
|
||||
void drawmenu_layer(void) {
|
||||
int x = 0, y = 0, w = 0;
|
||||
plw = hidepowerline ? 0 : drw->font->h / 2 + 1; // powerline size
|
||||
|
||||
// draw menu first using menu scheme
|
||||
drw_setscheme(drw, scheme[SchemeMenu]);
|
||||
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
||||
drw_rect(drw, 0, 0, mw, mh, 1, 1, col_menu, col_menu, alpha_menu, alpha_menu);
|
||||
|
||||
int numberWidth = 0;
|
||||
int modeWidth = 0;
|
||||
|
@ -486,15 +546,30 @@ void drawmenu(void) {
|
|||
y -= bh;
|
||||
mh = (lines + 1) * bh - bh + 2 * menumarginv;
|
||||
|
||||
if (!win) return;
|
||||
if (!protocol) {
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
|
||||
XResizeWindow(dpy, win, mw - 2 * sp - 2 * borderwidth, mh);
|
||||
drw_resize(drw, mw - 2 * sp - 2 * borderwidth, mh);
|
||||
} else {
|
||||
resizeclient();
|
||||
}
|
||||
}
|
||||
#if USEIMAGE
|
||||
else if (hideprompt && hideinput && hidemode && hidematchcount && hidecaps) {
|
||||
y -= bh;
|
||||
mh = (lines + 1) * bh - bh + 2 * menumarginv;
|
||||
|
||||
#if USEWAYLAND
|
||||
if (protocol) {
|
||||
state.width = mw;
|
||||
state.height = mh;
|
||||
|
||||
set_layer_size(&state, state.width, state.height);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
// declare functions
|
||||
static void drawmenu_layer(void);
|
||||
static void drawmenu(void);
|
||||
static int drawprompt(int x, int y, int w);
|
||||
static int drawinput(int x, int y, int w);
|
||||
|
|
|
@ -420,7 +420,7 @@ void resizetoimageheight(int imageheight) {
|
|||
} else { // top or bottom
|
||||
x = 0;
|
||||
y = menuposition ? 0 : wa.height - mh - ypos;
|
||||
mw = wa.width;
|
||||
mw = (menuwidth > 0 ? menuwidth : wa.width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,22 @@
|
|||
#include "drw.h"
|
||||
#include "../sl/main.h"
|
||||
|
||||
Clr transcheme[3]; // transition colorscheme
|
||||
void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha) {
|
||||
unsigned int hex;
|
||||
|
||||
Drw *drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap) {
|
||||
sscanf(col, "#%x", &hex);
|
||||
|
||||
double r = ((hex >> 16) & 0xFF) / 255.0;
|
||||
double g = ((hex >> 8) & 0xFF) / 255.0;
|
||||
double b = (hex & 0xFF) / 255.0;
|
||||
|
||||
cairo_set_source_rgba(cr, r, g, b, alpha / 255.0);
|
||||
}
|
||||
|
||||
Drw *drw_create_x11(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol) {
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
drw->protocol = protocol;
|
||||
drw->dpy = dpy;
|
||||
drw->screen = screen;
|
||||
drw->root = root;
|
||||
|
@ -31,6 +42,22 @@ Drw *drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned
|
|||
return drw;
|
||||
}
|
||||
|
||||
Drw *drw_create_wl(int protocol) {
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
drw->protocol = protocol;
|
||||
|
||||
return drw;
|
||||
}
|
||||
|
||||
void drw_create_surface_wl(Drw *drw, void *data, int32_t w, int32_t h) {
|
||||
drw->data = data;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
drw->surface = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
|
||||
drw->d = cairo_create(drw->surface);
|
||||
}
|
||||
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h) {
|
||||
if (!drw)
|
||||
return;
|
||||
|
@ -45,13 +72,17 @@ void drw_resize(Drw *drw, unsigned int w, unsigned int h) {
|
|||
}
|
||||
|
||||
void drw_free(Drw *drw) {
|
||||
|
||||
if (!drw->protocol) {
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
XFreeGC(drw->dpy, drw->gc);
|
||||
}
|
||||
|
||||
drw_font_free(drw->font);
|
||||
free(drw);
|
||||
}
|
||||
|
||||
static Fnt *xfont_create(Drw *drw, const char *fontname) {
|
||||
static Fnt *font_create(Drw *drw, const char *fontname) {
|
||||
Fnt *font;
|
||||
PangoFontMap *fontmap;
|
||||
PangoContext *context;
|
||||
|
@ -80,7 +111,7 @@ static Fnt *xfont_create(Drw *drw, const char *fontname) {
|
|||
return font;
|
||||
}
|
||||
|
||||
void xfont_free(Fnt *font) {
|
||||
void font_free(Fnt *font) {
|
||||
if (!font)
|
||||
return;
|
||||
if (font->layout)
|
||||
|
@ -94,126 +125,116 @@ Fnt* drw_font_create(Drw* drw, char *font[], size_t fontcount) {
|
|||
|
||||
Fnt *fnt = NULL;
|
||||
|
||||
fnt = xfont_create(drw, *font);
|
||||
fnt = font_create(drw, *font);
|
||||
|
||||
return (drw->font = fnt);
|
||||
}
|
||||
|
||||
void drw_font_free(Fnt *font) {
|
||||
if (font) {
|
||||
xfont_free(font);
|
||||
font_free(font);
|
||||
}
|
||||
}
|
||||
|
||||
void drw_clr_create(Drw *drw, Clr *dest, char *clrname, unsigned int alpha) {
|
||||
XColor color;
|
||||
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
if (!XAllocNamedColor(drw->dpy, drw->cmap, clrname, &color, dest))
|
||||
die("spmenu: cannot allocate color '%s'", clrname);
|
||||
|
||||
dest->red = color.red;
|
||||
dest->green = color.green;
|
||||
dest->blue = color.blue;
|
||||
|
||||
dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr * drw_scm_create(Drw *drw, char *clrnames[], unsigned int alphas[], size_t clrcount) {
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
|
||||
/* need at least two colors for a scheme */
|
||||
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XColor))))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < clrcount; i++)
|
||||
drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void drw_setscheme(Drw *drw, Clr *scm) {
|
||||
if (drw)
|
||||
drw->scheme = scm;
|
||||
}
|
||||
|
||||
void drw_settrans(Drw *drw, Clr *psc, Clr *nsc) {
|
||||
if (drw) {
|
||||
transcheme[0] = psc[ColBg]; transcheme[1] = nsc[ColBg]; transcheme[2] = psc[ColPwl];
|
||||
drw->scheme = transcheme;
|
||||
}
|
||||
}
|
||||
|
||||
void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash) {
|
||||
if (!drw || !drw->scheme)
|
||||
void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha) {
|
||||
if (!drw)
|
||||
return;
|
||||
|
||||
x = direction ? x : x + w;
|
||||
w = direction ? w : - w;
|
||||
unsigned int hh = slash ? (direction ? 0 : h) : h/2;
|
||||
|
||||
XPoint points[] = {
|
||||
{x , y },
|
||||
{x + w, y + hh },
|
||||
{x , y + h },
|
||||
};
|
||||
double hh = slash ? (direction ? 0 : h) : h / 2;
|
||||
|
||||
XPoint bg[] = {
|
||||
{x , y },
|
||||
{x + w, y },
|
||||
{x + w, y + h},
|
||||
{x , y + h},
|
||||
};
|
||||
cairo_surface_t *sf = NULL;
|
||||
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
|
||||
XFillPolygon(drw->dpy, drw->drawable, drw->gc, bg, 4, Convex, CoordModeOrigin);
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColFg].pixel);
|
||||
XFillPolygon(drw->dpy, drw->drawable, drw->gc, points, 3, Nonconvex, CoordModeOrigin);
|
||||
if (drw->protocol) {
|
||||
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
|
||||
} else {
|
||||
sf = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h);
|
||||
}
|
||||
cairo_t *cr = cairo_create(sf);
|
||||
|
||||
cairo_set_source_hex(cr, prevcol, prevalpha);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||
|
||||
cairo_rectangle(cr, x, y, w, h);
|
||||
cairo_fill(cr);
|
||||
|
||||
cairo_move_to(cr, x, y);
|
||||
cairo_line_to(cr, x + w, y + hh);
|
||||
cairo_line_to(cr, x, y + h);
|
||||
cairo_close_path(cr);
|
||||
|
||||
cairo_set_source_hex(cr, nextcol, nextalpha);
|
||||
cairo_fill(cr);
|
||||
|
||||
cairo_destroy(cr);
|
||||
cairo_surface_destroy(sf);
|
||||
}
|
||||
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) {
|
||||
if (!drw || !drw->scheme)
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert, char *fgcol, char *bgcol, int fgalpha, int bgalpha) {
|
||||
if (!drw) {
|
||||
return;
|
||||
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
||||
if (filled)
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
else
|
||||
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||
}
|
||||
|
||||
int xerrordummy(Display *dpy, XErrorEvent *ee) {
|
||||
return 0;
|
||||
cairo_surface_t *sf;
|
||||
|
||||
if (drw->protocol) {
|
||||
sf = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
|
||||
} else {
|
||||
sf = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h);
|
||||
}
|
||||
cairo_t *cr = cairo_create(sf);
|
||||
|
||||
if (!cr) {
|
||||
die("failed to create cairo context");
|
||||
}
|
||||
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup) {
|
||||
cairo_set_source_hex(cr, invert ? bgcol : fgcol, invert ? bgalpha : fgalpha);
|
||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||
|
||||
if (filled) {
|
||||
cairo_rectangle(cr, x, y, w, h);
|
||||
cairo_fill(cr);
|
||||
} else {
|
||||
cairo_rectangle(cr, x, y, w - 1, h - 1);
|
||||
cairo_stroke(cr);
|
||||
}
|
||||
|
||||
cairo_destroy(cr);
|
||||
cairo_surface_destroy(sf);
|
||||
}
|
||||
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup, char *fgcol, char *bgcol, int fgalpha, int bgalpha) {
|
||||
char buf[1024];
|
||||
int ty;
|
||||
unsigned int ew = 0;
|
||||
|
||||
size_t i, len;
|
||||
int render = x || y || w || h;
|
||||
char *t;
|
||||
|
||||
XSetErrorHandler(xerrordummy);
|
||||
|
||||
if (!drw || (render && !drw->scheme) || !text || !drw->font)
|
||||
if (!drw || !text || !drw->font) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!render) {
|
||||
w = ~w;
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
|
||||
drw->surface = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h);
|
||||
drw->d = cairo_create(drw->surface);
|
||||
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
|
||||
if (drw->protocol) {
|
||||
drw->surface = cairo_image_surface_create_for_data(drw->data, CAIRO_FORMAT_ARGB32, drw->w, drw->h, drw->w * 4);
|
||||
} else {
|
||||
drw->surface = cairo_xlib_surface_create(drw->dpy, drw->drawable, drw->visual, drw->w, drw->h);
|
||||
}
|
||||
drw->d = cairo_create(drw->surface);
|
||||
|
||||
// draw bg
|
||||
cairo_set_source_hex(drw->d, invert ? fgcol : bgcol, invert ? fgalpha : bgalpha);
|
||||
cairo_set_operator(drw->d, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_rectangle(drw->d, x - lpad, y, w + lpad, h);
|
||||
cairo_fill(drw->d);
|
||||
}
|
||||
|
||||
t = strdup(text);
|
||||
|
@ -237,8 +258,6 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
|
|||
markup = 0;
|
||||
|
||||
if (render) {
|
||||
ty = y + (h - drw->font->h) / 2;
|
||||
|
||||
if (markup) {
|
||||
pango_layout_set_markup(drw->font->layout, buf, len);
|
||||
} else {
|
||||
|
@ -247,12 +266,16 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
|
|||
|
||||
pango_layout_set_single_paragraph_mode(drw->font->layout, True);
|
||||
|
||||
cairo_set_source_rgb(drw->d, convert_color(drw->scheme->red), convert_color(drw->scheme->green), convert_color(drw->scheme->blue));
|
||||
cairo_move_to(drw->d, x, ty);
|
||||
// draw fg
|
||||
cairo_set_source_hex(drw->d, fgcol, fgalpha);
|
||||
cairo_move_to(drw->d, x, y + (h - drw->font->h) / 2);
|
||||
|
||||
// update and show layout
|
||||
pango_cairo_update_layout(drw->d, drw->font->layout);
|
||||
pango_cairo_show_layout(drw->d, drw->font->layout);
|
||||
|
||||
cairo_set_operator(drw->d, CAIRO_OPERATOR_SOURCE);
|
||||
|
||||
if (markup) // clear markup attributes
|
||||
pango_layout_set_attributes(drw->font->layout, NULL);
|
||||
}
|
||||
|
@ -269,14 +292,16 @@ void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
|||
if (!drw)
|
||||
return;
|
||||
|
||||
if (!drw->protocol) {
|
||||
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
|
||||
XSync(drw->dpy, False);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup) {
|
||||
if (!drw || !drw->font || !text)
|
||||
return 0;
|
||||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup);
|
||||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup, "#000000", "#000000", 255, 255);
|
||||
}
|
||||
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup) {
|
||||
|
@ -329,6 +354,6 @@ void drw_cur_free(Drw *drw, Cur *cursor) {
|
|||
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n, Bool markup) {
|
||||
unsigned int tmp = 0;
|
||||
if (drw && drw->font && text && n)
|
||||
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, markup);
|
||||
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n, markup, "#000000", "#000000", 255, 255);
|
||||
return MIN(n, tmp);
|
||||
}
|
||||
|
|
|
@ -6,40 +6,41 @@
|
|||
#include <pango/pango.h>
|
||||
#include <pango/pangocairo.h>
|
||||
|
||||
#define convert_color(x) (double)((x) / 65535.0)
|
||||
|
||||
typedef struct {
|
||||
Cursor cursor;
|
||||
} Cur;
|
||||
|
||||
typedef XColor Clr;
|
||||
|
||||
typedef struct Fnt {
|
||||
Display *dpy;
|
||||
unsigned int h;
|
||||
PangoLayout *layout;
|
||||
} Fnt;
|
||||
|
||||
enum { ColFg, ColBg, ColPwl }; /* Clr scheme index */
|
||||
|
||||
typedef struct {
|
||||
unsigned int w, h;
|
||||
int protocol;
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Visual *visual;
|
||||
unsigned int depth;
|
||||
void *data;
|
||||
Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
Fnt *font;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *d;
|
||||
} Drw;
|
||||
|
||||
/* Cairo color convertion */
|
||||
void cairo_set_source_hex(cairo_t* cr, const char *col, int alpha);
|
||||
|
||||
/* Drawable abstraction */
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
Drw *drw_create_x11(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap, int protocol);
|
||||
Drw *drw_create_wl(int protocol);
|
||||
void drw_create_surface_wl(Drw *drw, void *data, int32_t w, int32_t h);
|
||||
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
|
@ -50,24 +51,16 @@ unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int
|
|||
unsigned int drw_font_getwidth(Drw *drw, const char *text, Bool markup);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, char *clrname, unsigned int alpha);
|
||||
Clr *drw_scm_create(Drw *drw, char *clrnames[], unsigned int alphas[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
void drw_cur_free(Drw *drw, Cur *cursor);
|
||||
|
||||
/* Drawing context manipulation */
|
||||
void drw_setscheme(Drw *drw, Clr *scm);
|
||||
|
||||
/* Drawing functions */
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup);
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert, char *fgcol, char *bgcol, int fgalpha, int bgalpha);
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup, char *fgcol, char *bgcol, int fgalpha, int bgalpha);
|
||||
|
||||
/* Map functions */
|
||||
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
||||
|
||||
/* Powerline functions */
|
||||
void drw_settrans(Drw *drw, Clr *psc, Clr *nsc);
|
||||
void drw_arrow(Drw* drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash);
|
||||
void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash, char *prevcol, char *nextcol, int prevalpha, int nextalpha);
|
||||
|
|
13
libs/match.c
13
libs/match.c
|
@ -33,11 +33,7 @@ void fuzzymatch(void) {
|
|||
}
|
||||
// build list of matches
|
||||
if (eidx != -1) {
|
||||
// compute distance
|
||||
// add penalty if match starts late (log(sidx+2))
|
||||
//add penalty for long a match without many matching characters
|
||||
it->distance = log(sidx + 2) + (double)(eidx - sidx - text_len);
|
||||
// fprintf(stderr, "distance %s %f\n", it->text, it->distance);
|
||||
appenditem(it, &matches, &matchend);
|
||||
number_of_matches++;
|
||||
}
|
||||
|
@ -79,16 +75,20 @@ void fuzzymatch(void) {
|
|||
for (i = 0; i < preselected; i++) {
|
||||
if (sel && sel->right && (sel = sel->right) == next) {
|
||||
curr = next;
|
||||
calcoffsets();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calcoffsets();
|
||||
}
|
||||
|
||||
void match(void) {
|
||||
get_width();
|
||||
|
||||
if (fuzzy) {
|
||||
fuzzymatch();
|
||||
return;
|
||||
}
|
||||
|
||||
static char **tokv = NULL;
|
||||
static int tokn = 0;
|
||||
|
||||
|
@ -103,6 +103,7 @@ void match(void) {
|
|||
for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
|
||||
if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
|
||||
die("spmenu: cannot realloc %u bytes:", tokn * sizeof *tokv);
|
||||
|
||||
len = tokc ? strlen(tokv[0]) : 0;
|
||||
|
||||
matches = lhpprefix = lprefix = lsubstr = matchend = hpprefixend = prefixend = substrend = NULL;
|
||||
|
|
|
@ -9,83 +9,44 @@ void init_appearance(void) {
|
|||
|
||||
char cbuf[8];
|
||||
|
||||
// set alpha
|
||||
alphas[SchemeLArrow][ColFg] = alpha_larrowfg;
|
||||
alphas[SchemeLArrow][ColBg] = alpha_larrowbg;
|
||||
alphas[SchemeRArrow][ColFg] = alpha_rarrowfg;
|
||||
alphas[SchemeRArrow][ColBg] = alpha_rarrowbg;
|
||||
alphas[SchemeItemNorm1][ColFg] = alpha_itemnormfg;
|
||||
alphas[SchemeItemNorm1][ColBg] = alpha_itemnormbg;
|
||||
alphas[SchemeItemNorm2][ColFg] = alpha_itemnormfg2;
|
||||
alphas[SchemeItemNorm2][ColBg] = alpha_itemnormbg2;
|
||||
alphas[SchemeItemSel][ColFg] = alpha_itemselfg;
|
||||
alphas[SchemeItemSel][ColBg] = alpha_itemselbg;
|
||||
alphas[SchemeItemMarked][ColFg] = alpha_itemmarkedfg;
|
||||
alphas[SchemeItemMarked][ColBg] = alpha_itemmarkedbg;
|
||||
alphas[SchemeItemNormPri][ColFg] = alpha_itemnormprifg;
|
||||
alphas[SchemeItemNormPri][ColBg] = alpha_itemnormpribg;
|
||||
alphas[SchemeItemSelPri][ColFg] = alpha_itemselprifg;
|
||||
alphas[SchemeItemSelPri][ColBg] = alpha_itemselpribg;
|
||||
alphas[SchemeMenu][ColBg] = alpha_menu;
|
||||
alphas[SchemeInput][ColFg] = alpha_inputfg;
|
||||
alphas[SchemeInput][ColBg] = alpha_inputbg;
|
||||
alphas[SchemePrompt][ColFg] = alpha_promptfg;
|
||||
alphas[SchemePrompt][ColBg] = alpha_promptbg;
|
||||
alphas[SchemeNormHighlight][ColFg] = alpha_hlnormfg;
|
||||
alphas[SchemeNormHighlight][ColBg] = alpha_hlnormbg;
|
||||
alphas[SchemeSelHighlight][ColFg] = alpha_hlselfg;
|
||||
alphas[SchemeSelHighlight][ColBg] = alpha_hlselbg;
|
||||
alphas[SchemeCaret][ColFg] = alpha_caretfg;
|
||||
alphas[SchemeCaret][ColBg] = alpha_caretbg;
|
||||
alphas[SchemeNumber][ColFg] = alpha_numfg;
|
||||
alphas[SchemeNumber][ColBg] = alpha_numbg;
|
||||
alphas[SchemeMode][ColFg] = alpha_modefg;
|
||||
alphas[SchemeMode][ColBg] = alpha_modebg;
|
||||
alphas[SchemeCaps][ColFg] = alpha_capsfg;
|
||||
alphas[SchemeCaps][ColBg] = alpha_capsbg;
|
||||
alphas[SchemeBorder][ColBg] = alpha_border;
|
||||
|
||||
// create color schemes from array
|
||||
scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
|
||||
scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], alphas[i], 2);
|
||||
|
||||
for (i = 0; i < LENGTH(colors) && i < LENGTH(alphas); i++)
|
||||
scheme[i] = drw_scm_create(drw, colors[i], alphas[i], 2);
|
||||
|
||||
for (i = 0; i < LENGTH(textcolors) && i < LENGTH(textclrs); i++)
|
||||
drw_clr_create(drw, &textclrs[i], textcolors[i], 0);
|
||||
if (i == 0)
|
||||
drw_clr_create(drw, &textclrs[i++], "#000000", 0);
|
||||
for (i = 0; i < LENGTH(textcolors) && i < LENGTH(txtcols); i++) {
|
||||
txtcols[i] = textcolors[i];
|
||||
}
|
||||
if (i == 0) {
|
||||
txtcols[i] = "#000000";
|
||||
}
|
||||
for (; i < 7; i++) {
|
||||
snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x",
|
||||
!!(i & 1) * 0x7f,
|
||||
!!(i & 2) * 0x7f,
|
||||
!!(i & 4) * 0x7f);
|
||||
drw_clr_create(drw, &textclrs[i], cbuf, 0);
|
||||
txtcols[i] = cbuf;
|
||||
}
|
||||
if (i == 7) {
|
||||
txtcols[i] = "#000000";
|
||||
}
|
||||
if (i == 8) {
|
||||
txtcols[i] = "#333333";
|
||||
}
|
||||
if (i == 7)
|
||||
drw_clr_create(drw, &textclrs[i++], "#000000", 0);
|
||||
if (i == 8)
|
||||
drw_clr_create(drw, &textclrs[i++], "#333333", 0);
|
||||
for (; i < 16; i++) {
|
||||
snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x",
|
||||
!!(i & 1) * 0xff,
|
||||
!!(i & 2) * 0xff,
|
||||
!!(i & 4) * 0xff);
|
||||
drw_clr_create(drw, &textclrs[i], cbuf, 0);
|
||||
txtcols[i] = cbuf;
|
||||
}
|
||||
for (; i < 6 * 6 * 6 + 16; i++) {
|
||||
snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x",
|
||||
sixd_to_8bit(((i - 16) / 36) % 6),
|
||||
sixd_to_8bit(((i - 16) / 6) % 6),
|
||||
sixd_to_8bit(((i - 16)) % 6));
|
||||
drw_clr_create(drw, &textclrs[i], cbuf, 0);
|
||||
txtcols[i] = cbuf;
|
||||
}
|
||||
for (; i < 256; i++) {
|
||||
snprintf(cbuf, sizeof(cbuf), "#%02x%02x%02x",
|
||||
0x08 + (i - 6 * 6 * 6 - 16) * 0x0a,
|
||||
0x08 + (i - 6 * 6 * 6 - 16) * 0x0a,
|
||||
0x08 + (i - 6 * 6 * 6 - 16) * 0x0a);
|
||||
drw_clr_create(drw, &textclrs[i], cbuf, 0);
|
||||
txtcols[i] = cbuf;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,3 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
static void init_appearance(void);
|
||||
|
||||
// Color schemes
|
||||
enum {
|
||||
SchemeLArrow,
|
||||
SchemeRArrow,
|
||||
SchemeItemNorm1,
|
||||
SchemeItemNorm2,
|
||||
SchemeItemSel,
|
||||
SchemeItemNormPri,
|
||||
SchemeItemSelPri,
|
||||
SchemeItemMarked,
|
||||
SchemeMenu,
|
||||
SchemeInput,
|
||||
SchemePrompt,
|
||||
SchemeNormHighlight,
|
||||
SchemeSelHighlight,
|
||||
SchemeCaret,
|
||||
SchemeNumber,
|
||||
SchemeMode,
|
||||
SchemeBorder,
|
||||
SchemeCaps,
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
void readstdin(void) {
|
||||
char buf[sizeof text], *p;
|
||||
size_t i, imax = 0, itemsiz = 0;
|
||||
size_t i, itemsiz = 0;
|
||||
unsigned int tmpmax = 0;
|
||||
|
||||
if (passwd) {
|
||||
|
@ -32,7 +32,6 @@ void readstdin(void) {
|
|||
drw_font_getexts(drw->font, buf, strlen(buf), &tmpmax, NULL, True);
|
||||
if (tmpmax > inputw) {
|
||||
inputw = tmpmax;
|
||||
imax = i;
|
||||
}
|
||||
|
||||
items[i].index = i;
|
||||
|
@ -60,7 +59,6 @@ void readstdin(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
inputw = items ? TEXTWM(items[imax].text) : 0;
|
||||
lines = MIN(lines, i);
|
||||
}
|
||||
|
||||
|
@ -128,7 +126,6 @@ void readfile(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
inputw = items ? TEXTWM(items[i].text) : 0;
|
||||
lines = columns == 1 ? i : MIN(i, lines); // i = number of items
|
||||
|
||||
#if USEIMAGE
|
||||
|
@ -141,8 +138,11 @@ void readfile(void) {
|
|||
listcount = i;
|
||||
listchanged = 1;
|
||||
|
||||
// prevents state->buffer from being NULL
|
||||
if (!protocol) {
|
||||
resizeclient();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
free(items);
|
||||
items = list_items;
|
||||
|
|
|
@ -7,7 +7,7 @@ void theme_load(void) {
|
|||
const char *dest;
|
||||
|
||||
// don't load configuration
|
||||
if (!loadconfig) return;
|
||||
if (!loadtheme) return;
|
||||
|
||||
// get path for configuration file
|
||||
if (!argtheme) {
|
||||
|
@ -212,125 +212,125 @@ void theme_load(void) {
|
|||
|
||||
// items
|
||||
if (config_setting_lookup_string(conf, "itemnormfg", &dest))
|
||||
strcpy(colors[SchemeItemNorm1][ColFg], strdup(dest));
|
||||
strcpy(col_itemnormfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormbg", &dest))
|
||||
strcpy(colors[SchemeItemNorm1][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormfg2", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColFg], strdup(dest));
|
||||
strcpy(col_itemnormfg2, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemnormfg", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormfg2, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormbg2", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormbg2, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemnormbg", &dest))
|
||||
strcpy(colors[SchemeItemNorm2][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormbg2, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselfg", &dest))
|
||||
strcpy(colors[SchemeItemSel][ColFg], strdup(dest));
|
||||
strcpy(col_itemselfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselbg", &dest))
|
||||
strcpy(colors[SchemeItemSel][ColBg], strdup(dest));
|
||||
strcpy(col_itemselbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemmarkedfg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColFg], strdup(dest));
|
||||
strcpy(col_itemmarkedfg, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemselfg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColFg], strdup(dest));
|
||||
strcpy(col_itemmarkedfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemmarkedbg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColBg], strdup(dest));
|
||||
strcpy(col_itemmarkedbg, strdup(dest));
|
||||
else if (config_setting_lookup_string(conf, "itemselbg", &dest))
|
||||
strcpy(colors[SchemeItemMarked][ColBg], strdup(dest));
|
||||
strcpy(col_itemmarkedbg, strdup(dest));
|
||||
|
||||
// items with priority
|
||||
if (config_setting_lookup_string(conf, "itemnormprifg", &dest))
|
||||
strcpy(colors[SchemeItemNormPri][ColFg], strdup(dest));
|
||||
strcpy(col_itemnormprifg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemnormpribg", &dest))
|
||||
strcpy(colors[SchemeItemNormPri][ColBg], strdup(dest));
|
||||
strcpy(col_itemnormpribg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselprifg", &dest))
|
||||
strcpy(colors[SchemeItemSelPri][ColFg], strdup(dest));
|
||||
strcpy(col_itemselprifg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "itemselpribg", &dest))
|
||||
strcpy(colors[SchemeItemSelPri][ColBg], strdup(dest));
|
||||
strcpy(col_itemselpribg, strdup(dest));
|
||||
|
||||
// input
|
||||
if (config_setting_lookup_string(conf, "inputfg", &dest))
|
||||
strcpy(colors[SchemeInput][ColFg], strdup(dest));
|
||||
strcpy(col_inputfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "inputbg", &dest))
|
||||
strcpy(colors[SchemeInput][ColBg], strdup(dest));
|
||||
strcpy(col_inputbg, strdup(dest));
|
||||
|
||||
// menu
|
||||
if (config_setting_lookup_string(conf, "menu", &dest))
|
||||
strcpy(colors[SchemeMenu][ColBg], strdup(dest));
|
||||
strcpy(col_menu, strdup(dest));
|
||||
|
||||
// prompt
|
||||
if (config_setting_lookup_string(conf, "promptfg", &dest))
|
||||
strcpy(colors[SchemePrompt][ColFg], strdup(dest));
|
||||
strcpy(col_promptfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "promptbg", &dest))
|
||||
strcpy(colors[SchemePrompt][ColBg], strdup(dest));
|
||||
strcpy(col_promptbg, strdup(dest));
|
||||
|
||||
// arrows
|
||||
if (config_setting_lookup_string(conf, "larrowfg", &dest))
|
||||
strcpy(colors[SchemeLArrow][ColFg], strdup(dest));
|
||||
strcpy(col_larrowfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "larrowbg", &dest))
|
||||
strcpy(colors[SchemeLArrow][ColBg], strdup(dest));
|
||||
strcpy(col_larrowbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "rarrowfg", &dest))
|
||||
strcpy(colors[SchemeRArrow][ColFg], strdup(dest));
|
||||
strcpy(col_rarrowfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "rarrowbg", &dest))
|
||||
strcpy(colors[SchemeRArrow][ColBg], strdup(dest));
|
||||
strcpy(col_rarrowbg, strdup(dest));
|
||||
|
||||
// highlight
|
||||
if (config_setting_lookup_string(conf, "hlnormfg", &dest))
|
||||
strcpy(colors[SchemeNormHighlight][ColFg], strdup(dest));
|
||||
strcpy(col_hlnormfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "hlnormbg", &dest))
|
||||
strcpy(colors[SchemeNormHighlight][ColBg], strdup(dest));
|
||||
strcpy(col_hlnormbg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "hlselfg", &dest))
|
||||
strcpy(colors[SchemeSelHighlight][ColFg], strdup(dest));
|
||||
strcpy(col_hlselfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "hlselbg", &dest))
|
||||
strcpy(colors[SchemeSelHighlight][ColBg], strdup(dest));
|
||||
strcpy(col_hlselbg, strdup(dest));
|
||||
|
||||
// number
|
||||
if (config_setting_lookup_string(conf, "numfg", &dest))
|
||||
strcpy(colors[SchemeNumber][ColFg], strdup(dest));
|
||||
strcpy(col_numfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "numbg", &dest))
|
||||
strcpy(colors[SchemeNumber][ColBg], strdup(dest));
|
||||
strcpy(col_numbg, strdup(dest));
|
||||
|
||||
// mode
|
||||
if (config_setting_lookup_string(conf, "modefg", &dest))
|
||||
strcpy(colors[SchemeMode][ColFg], strdup(dest));
|
||||
strcpy(col_modefg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "modebg", &dest))
|
||||
strcpy(colors[SchemeMode][ColBg], strdup(dest));
|
||||
strcpy(col_modebg, strdup(dest));
|
||||
|
||||
// caps
|
||||
if (config_setting_lookup_string(conf, "capsfg", &dest))
|
||||
strcpy(colors[SchemeCaps][ColFg], strdup(dest));
|
||||
strcpy(col_capsfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "capsbg", &dest))
|
||||
strcpy(colors[SchemeCaps][ColBg], strdup(dest));
|
||||
strcpy(col_capsbg, strdup(dest));
|
||||
|
||||
// border
|
||||
if (config_setting_lookup_string(conf, "border", &dest))
|
||||
strcpy(colors[SchemeBorder][ColBg], strdup(dest));
|
||||
strcpy(col_border, strdup(dest));
|
||||
|
||||
// caret
|
||||
if (config_setting_lookup_string(conf, "caretfg", &dest))
|
||||
strcpy(colors[SchemeCaret][ColFg], strdup(dest));
|
||||
strcpy(col_caretfg, strdup(dest));
|
||||
|
||||
if (config_setting_lookup_string(conf, "caretbg", &dest))
|
||||
strcpy(colors[SchemeCaret][ColBg], strdup(dest));
|
||||
strcpy(col_caretbg, strdup(dest));
|
||||
|
||||
// sgr colors
|
||||
if (config_setting_lookup_string(conf, "sgr0", &dest))
|
||||
|
|
6
libs/wl/inc.c
Normal file
6
libs/wl/inc.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#if USEWAYLAND
|
||||
#include "wayland.c"
|
||||
#include "init.c"
|
||||
#endif
|
6
libs/wl/inc.h
Normal file
6
libs/wl/inc.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#if USEWAYLAND
|
||||
#include "wayland.h"
|
||||
#include "init.h"
|
||||
#endif
|
64
libs/wl/init.c
Normal file
64
libs/wl/init.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
void prepare_window_size_wl(void) {
|
||||
sp = menupaddingh;
|
||||
vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
|
||||
|
||||
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight);
|
||||
lines = MAX(lines, 0);
|
||||
reallines = lines;
|
||||
|
||||
lrpad = drw->font->h + textpadding;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void handle_wl(void) {
|
||||
if (!setlocale(LC_CTYPE, "")) {
|
||||
die("spmenu: no locale support");
|
||||
}
|
||||
|
||||
prepare_window_size_wl();
|
||||
promptw = (prompt && *prompt) ? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0;
|
||||
|
||||
allow_draw = 1;
|
||||
|
||||
init_keys(&state);
|
||||
init_disp(&state);
|
||||
|
||||
if (no_display) {
|
||||
protocol = 0;
|
||||
handle();
|
||||
return;
|
||||
}
|
||||
|
||||
create_layer(&state, "spmenu");
|
||||
|
||||
mw = (menuwidth > 0 ? menuwidth : output_width);
|
||||
mh = (lines + 1) * bh + 2 * menumarginv;
|
||||
|
||||
if (menuposition == 2) {
|
||||
mw = MIN(MAX(max_textw() + promptw, minwidth), output_width);
|
||||
}
|
||||
|
||||
state.width = mw;
|
||||
state.height = mh;
|
||||
|
||||
set_layer_size(&state, state.width, state.height);
|
||||
|
||||
anchor_layer(&state, menuposition);
|
||||
set_exclusive_zone(&state, -1);
|
||||
set_keyboard(&state, 1);
|
||||
add_layer_listener(&state);
|
||||
set_visible_layer(&state);
|
||||
|
||||
roundtrip(&state);
|
||||
|
||||
match();
|
||||
draw_sf(&state);
|
||||
|
||||
while (wl_display_dispatch(state.display) != -1) {
|
||||
}
|
||||
|
||||
wl_display_disconnect(state.display);
|
||||
}
|
3
libs/wl/init.h
Normal file
3
libs/wl/init.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
static void handle_wl(void);
|
43
libs/wl/shm.c
Normal file
43
libs/wl/shm.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
void randname(char *buf) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
long r = ts.tv_nsec;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
buf[i] = 'A'+(r&15)+(r&16)*2;
|
||||
r >>= 5;
|
||||
}
|
||||
}
|
||||
|
||||
int anonymous_shm_open(void) {
|
||||
char name[] = "/shm-XXXXXX";
|
||||
int retries = 100;
|
||||
|
||||
do {
|
||||
randname(name + strlen(name) - 6);
|
||||
|
||||
--retries;
|
||||
|
||||
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
|
||||
if (fd >= 0) {
|
||||
shm_unlink(name);
|
||||
return fd;
|
||||
}
|
||||
} while (retries > 0 && errno == EEXIST);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int create_shm_file(off_t size) {
|
||||
int fd = anonymous_shm_open();
|
||||
if (fd < 0) {
|
||||
return fd;
|
||||
}
|
||||
|
||||
if (ftruncate(fd, size) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
666
libs/wl/wayland.c
Normal file
666
libs/wl/wayland.c
Normal file
|
@ -0,0 +1,666 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#include "shm.c"
|
||||
|
||||
struct wl_buffer *create_buffer(struct state *state) {
|
||||
int32_t width = state->width;
|
||||
int32_t height = state->height;
|
||||
|
||||
uint32_t stride = width * 4;
|
||||
size_t siz = stride * height;
|
||||
|
||||
int fd = create_shm_file(siz);
|
||||
assert(fd != -1);
|
||||
|
||||
void *data = mmap(NULL, siz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
if (data == MAP_FAILED) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wl_shm_pool *pool = wl_shm_create_pool(state->shm, fd, siz);
|
||||
|
||||
struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0,
|
||||
width, height, stride, WL_SHM_FORMAT_ARGB8888);
|
||||
|
||||
wl_shm_pool_destroy(pool);
|
||||
|
||||
wl_buffer_add_listener(buffer, &buffer_listener, state);
|
||||
|
||||
state->data = data;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* I fucking hate this code, but I'm not sure how else to do it.
|
||||
*
|
||||
* PLEASE submit a patch if you have an improvement.
|
||||
*/
|
||||
int is_correct_modifier(struct state *state, char *modifier) {
|
||||
int altPress = xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
|
||||
int shiftPress = xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
|
||||
int ctrlPress = xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
|
||||
int logoPress = xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED);
|
||||
|
||||
if (!strcmp(modifier, WL_CtrlShift) && shiftPress && ctrlPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_CtrlShiftSuper) && shiftPress && ctrlPress && logoPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_CtrlSuper) && ctrlPress && logoPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_CtrlAlt) && altPress && ctrlPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_CtrlAltShift) && ctrlPress && altPress && shiftPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_CtrlAltShiftSuper) && ctrlPress && altPress && shiftPress && logoPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_CtrlAltSuper) && ctrlPress && altPress && logoPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_AltShift) && altPress && shiftPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_Shift) && shiftPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_Ctrl) && ctrlPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_Alt) && altPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_Super) && logoPress) {
|
||||
return 0;
|
||||
} else if (!strcmp(modifier, WL_None) && !altPress && !shiftPress && !ctrlPress && !logoPress) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_keysym_t sym) {
|
||||
int i = 0;
|
||||
char buf[8];
|
||||
|
||||
if (key_state != WL_KEYBOARD_KEY_STATE_PRESSED) { // Only activate on press, not release
|
||||
return;
|
||||
}
|
||||
|
||||
if (xkb_keysym_to_lower(sym) == wlhkeys[0].keysym && !is_correct_modifier(state, wlhkeys[0].modifier) && wlhkeys[0].func) {
|
||||
wlhkeys[0].func(&(wlhkeys[0].arg));
|
||||
}
|
||||
|
||||
for (i = 0; i < LENGTH(wl_keys); i++) {
|
||||
if (ignoreglobalkeys) break;
|
||||
|
||||
if (xkb_keysym_to_lower(sym) == wl_keys[i].keysym && !is_correct_modifier(state, wl_keys[i].modifier) && wl_keys[i].func) {
|
||||
if ((wl_keys[i].mode && curMode) || wl_keys[i].mode == -1) {
|
||||
wl_keys[i].func(&(wl_keys[i].arg));
|
||||
return;
|
||||
} else if (!wl_keys[i].mode && !curMode) {
|
||||
wl_keys[i].func(&(wl_keys[i].arg));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < LENGTH(wl_ckeys); i++) {
|
||||
if (ignoreconfkeys) break;
|
||||
|
||||
if (xkb_keysym_to_lower(sym) == wl_ckeys[i].keysym && !is_correct_modifier(state, wl_ckeys[i].modifier) && wl_ckeys[i].func) {
|
||||
if ((wl_ckeys[i].mode && curMode) || wl_ckeys[i].mode == -1) {
|
||||
wl_ckeys[i].func(&(wl_ckeys[i].arg));
|
||||
return;
|
||||
} else if (!wl_ckeys[i].mode && !curMode) {
|
||||
wl_ckeys[i].func(&(wl_ckeys[i].arg));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xkb_keysym_to_lower(sym) == XKB_KEY_Escape) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!type || !curMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (xkb_keysym_to_utf8(sym, buf, 8)) {
|
||||
if (allowkeys) {
|
||||
insert(buf, strnlen(buf, 8));
|
||||
} else {
|
||||
allowkeys = !allowkeys;
|
||||
}
|
||||
|
||||
drawmenu();
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
|
||||
struct state *state = data;
|
||||
int ocapslockstate = capslockstate;
|
||||
|
||||
xkb_state_update_mask(state->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
||||
|
||||
if (xkb_state_mod_name_is_active(state->xkb_state, XKB_MOD_NAME_CAPS, XKB_STATE_MODS_EFFECTIVE)) {
|
||||
capslockstate = 1;
|
||||
} else {
|
||||
capslockstate = 0;
|
||||
}
|
||||
|
||||
if (ocapslockstate != capslockstate) {
|
||||
strncpy(capstext, capslockstate ? capslockontext : capslockofftext, 15);
|
||||
drawmenu();
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) {
|
||||
struct state *state = data;
|
||||
|
||||
state->delay = delay;
|
||||
|
||||
if (rate > 0) {
|
||||
state->period = 1000 / rate;
|
||||
} else {
|
||||
state->period = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state) {
|
||||
struct state *state = data;
|
||||
|
||||
enum wl_keyboard_key_state key_state = _key_state;
|
||||
|
||||
strncpy(capstext, capslockstate ? capslockontext : capslockofftext, 15);
|
||||
|
||||
xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb_state, key + 8);
|
||||
keypress_wl(state, key_state, sym);
|
||||
|
||||
if (key_state == WL_KEYBOARD_KEY_STATE_PRESSED && state->period >= 0) {
|
||||
state->repeat_key_state = key_state;
|
||||
state->repeat_sym = sym;
|
||||
|
||||
struct itimerspec spec = { 0 };
|
||||
|
||||
spec.it_value.tv_sec = state->delay / 1000;
|
||||
spec.it_value.tv_nsec = (state->delay % 1000) * 1000000l;
|
||||
|
||||
timerfd_settime(state->timer, 0, &spec, NULL);
|
||||
} else if (key_state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||
struct itimerspec spec = { 0 };
|
||||
|
||||
timerfd_settime(state->timer, 0, &spec, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size) {
|
||||
struct state *state = data;
|
||||
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
|
||||
close(fd);
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (map_shm == MAP_FAILED) {
|
||||
close(fd);
|
||||
die("MAP_FAILED");
|
||||
return;
|
||||
}
|
||||
state->xkb_keymap = xkb_keymap_new_from_string(state->xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, 0);
|
||||
munmap(map_shm, size);
|
||||
close(fd);
|
||||
state->xkb_state = xkb_state_new(state->xkb_keymap);
|
||||
}
|
||||
|
||||
void buttonpress_wl(uint32_t button, double ex, double ey) {
|
||||
struct item *item;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w;
|
||||
int h = bh;
|
||||
int xpad = 0;
|
||||
int item_num = 0;
|
||||
unsigned int i, click;
|
||||
|
||||
if (ex == 0 && ey == 0) {
|
||||
return; // While it is possible to click at this position, usually it means we're outside the window area.
|
||||
}
|
||||
|
||||
if (!hidepowerline) {
|
||||
x = xpad = plw;
|
||||
}
|
||||
|
||||
x += menumarginh;
|
||||
|
||||
int larrowWidth = 0;
|
||||
int rarrowWidth = 0;
|
||||
int numberWidth = 0;
|
||||
int modeWidth = 0;
|
||||
int capsWidth = 0;
|
||||
|
||||
if (!hidelarrow) larrowWidth = pango_leftarrow ? TEXTWM(leftarrow) : TEXTW(leftarrow);
|
||||
if (!hiderarrow) rarrowWidth = pango_rightarrow ? TEXTWM(rightarrow) : TEXTW(rightarrow);
|
||||
if (!hidematchcount) numberWidth = pango_numbers ? TEXTWM(numbers) : TEXTW(numbers);
|
||||
if (!hidemode) modeWidth = pango_mode ? TEXTWM(modetext) : TEXTW(modetext);
|
||||
if (!hidecaps) capsWidth = pango_caps ? TEXTWM(capstext) : TEXTW(capstext);
|
||||
|
||||
if (!strcmp(capstext, "")) capsWidth = 0; // No caps lock width for no chars
|
||||
|
||||
click = ClickWindow; // Used as a default, will be overriden.
|
||||
|
||||
// check click position and override the value of click
|
||||
if (ex < x + promptw + powerlineprompt ? plw : 0) { // prompt
|
||||
click = ClickPrompt;
|
||||
} else if ((ex > mw - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) && !hidecaps && capsWidth) { // caps lock indicator
|
||||
click = ClickCaps;
|
||||
} else if (ex > mw - modeWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) { // mode indicator
|
||||
click = ClickMode;
|
||||
} else if (ex > mw - modeWidth - numberWidth - capsWidth - 2 * sp - 2 * borderwidth - menumarginh) { // match count
|
||||
click = ClickNumber;
|
||||
} else { // input
|
||||
w = (lines > 0 || !matches) ? mw - x : inputw;
|
||||
|
||||
if ((lines <= 0 && ex >= 0 && ex <= x + w + promptw +
|
||||
((!prev || !curr->left) ? larrowWidth : 0)) ||
|
||||
(lines > 0 && ey >= y && ey <= y + h)) {
|
||||
|
||||
click = ClickInput;
|
||||
}
|
||||
}
|
||||
|
||||
// item click
|
||||
if (lines > 0) {
|
||||
// vertical list
|
||||
w = mw - x;
|
||||
for (item = curr; item != next; item = item->right) {
|
||||
if (item_num++ == lines) {
|
||||
item_num = 1;
|
||||
x += w / columns;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
y += h;
|
||||
|
||||
// ClickSelItem, called function doesn't matter
|
||||
if (ey >= y && ey <= (y + h) && ex >= x && ex <= (x + w / columns)) {
|
||||
for (i = 0; i < LENGTH(wl_buttons); i++) {
|
||||
if (ignoreglobalmouse) break;
|
||||
if (wl_buttons[i].click == ClickSelItem && wl_buttons[i].button == button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (wl_buttons[i].click == ClickItem) {
|
||||
click = ClickItem;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < LENGTH(wl_cbuttons); i++) {
|
||||
if (ignoreconfmouse) break;
|
||||
if (wl_cbuttons[i].click == ClickSelItem && wl_cbuttons[i].button == button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (wl_cbuttons[i].click == ClickItem) {
|
||||
click = ClickItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (matches) {
|
||||
x += inputw;
|
||||
w = larrowWidth;
|
||||
if (prev && curr->left) {
|
||||
if (ex >= x && ex <= x + w) {
|
||||
click = ClickLArrow;
|
||||
}
|
||||
}
|
||||
|
||||
for (item = curr; item != next; item = item->right) {
|
||||
x += w;
|
||||
w = MIN(TEXTW(item->text), mw - x - rarrowWidth);
|
||||
if (ex >= x && ex <= x + w) {
|
||||
for (i = 0; i < LENGTH(wl_buttons); i++) {
|
||||
if (ignoreglobalmouse) break;
|
||||
if (wl_buttons[i].click == ClickSelItem && wl_buttons[i].button == button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (wl_buttons[i].click == ClickItem) {
|
||||
click = ClickItem;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < LENGTH(wl_cbuttons); i++) {
|
||||
if (ignoreconfmouse) break;
|
||||
if (wl_cbuttons[i].click == ClickSelItem && wl_cbuttons[i].button == button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (wl_cbuttons[i].click == ClickItem) {
|
||||
click = ClickItem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// right arrow
|
||||
w = rarrowWidth;
|
||||
x = mw - w;
|
||||
if (next && ex >= x && ex <= x + w) {
|
||||
click = ClickRArrow;
|
||||
}
|
||||
}
|
||||
|
||||
// go through mouse button array and run function
|
||||
for (i = 0; i < LENGTH(wl_buttons); i++) {
|
||||
if (ignoreglobalmouse) break;
|
||||
if (click == wl_buttons[i].click && wl_buttons[i].func && wl_buttons[i].button == button)
|
||||
wl_buttons[i].func(&wl_buttons[i].arg);
|
||||
}
|
||||
|
||||
// go through mouse config array and run function
|
||||
for (i = 0; i < LENGTH(wl_cbuttons); i++) {
|
||||
if (ignoreconfmouse) break;
|
||||
if (click == wl_cbuttons[i].click && wl_cbuttons[i].func && wl_cbuttons[i].button == button)
|
||||
wl_cbuttons[i].func(&wl_cbuttons[i].arg);
|
||||
}
|
||||
}
|
||||
|
||||
void pointer_motion_handler(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y) {
|
||||
mouse_x = wl_fixed_to_int(x);
|
||||
mouse_y = wl_fixed_to_int(y);
|
||||
}
|
||||
|
||||
void pointer_button_handler(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
||||
if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||
return; // We don't want a release event to count as a click, only the initial press.
|
||||
}
|
||||
|
||||
buttonpress_wl(button, mouse_x, mouse_y);
|
||||
}
|
||||
|
||||
void seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps) {
|
||||
struct state *state = data;
|
||||
|
||||
if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
|
||||
state->keyboard = wl_seat_get_keyboard(seat);
|
||||
state->pointer = wl_seat_get_pointer(seat);
|
||||
wl_keyboard_add_listener(state->keyboard, &keyboard_listener, state);
|
||||
wl_pointer_add_listener(state->pointer, &pointer_listener, state);
|
||||
}
|
||||
}
|
||||
|
||||
void output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t output_transform) {
|
||||
output_physical_width = physical_width;
|
||||
output_physical_height = physical_height;
|
||||
}
|
||||
|
||||
void output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
|
||||
output_width = width;
|
||||
output_height = height;
|
||||
}
|
||||
|
||||
void output_scale(void *data, struct wl_output *wl_output, int32_t factor) {
|
||||
struct output *output = data;
|
||||
|
||||
output->scale = factor;
|
||||
}
|
||||
|
||||
void output_name(void *data, struct wl_output *wl_output, const char *name) {
|
||||
struct output *output = data;
|
||||
struct state *state = output->state;
|
||||
|
||||
char *outname = state->output_name;
|
||||
|
||||
if (!state->output && outname && strcmp(outname, name) == 0) {
|
||||
state->output = output;
|
||||
}
|
||||
}
|
||||
|
||||
void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) {
|
||||
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||
}
|
||||
|
||||
void layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface) {
|
||||
cleanup();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void zero() {
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
void draw_sf(struct state *state) {
|
||||
if (!allow_draw) { // No drawing if disabled
|
||||
return;
|
||||
}
|
||||
|
||||
// create buffer to draw on
|
||||
state->buffer = create_buffer(state);
|
||||
|
||||
if (drw == NULL) {
|
||||
die("spmenu: drw == NULL");
|
||||
}
|
||||
|
||||
if (state->buffer == NULL) {
|
||||
die("state->buffer == null");
|
||||
}
|
||||
|
||||
drw_create_surface_wl(drw, state->data, state->width, state->height);
|
||||
|
||||
drawmenu_layer();
|
||||
|
||||
wl_surface_set_buffer_scale(state->surface, 1);
|
||||
wl_surface_attach(state->surface, state->buffer, 0, 0);
|
||||
wl_surface_damage(state->surface, 0, 0, state->width, state->height);
|
||||
wl_surface_commit(state->surface);
|
||||
}
|
||||
|
||||
void global_handler(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
|
||||
struct state *state = data;
|
||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||
state->compositor = wl_registry_bind(registry, name,
|
||||
&wl_compositor_interface, 4);
|
||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||
state->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
||||
} else if (strcmp(interface, wl_seat_interface.name) == 0 && has_keys) {
|
||||
struct wl_seat *seat = wl_registry_bind(registry, name,
|
||||
&wl_seat_interface, 4);
|
||||
wl_seat_add_listener(seat, &seat_listener, state);
|
||||
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||
state->layer_shell = wl_registry_bind(registry, name,
|
||||
&zwlr_layer_shell_v1_interface, 1);
|
||||
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||
struct output *output = calloc(1, sizeof(struct output));
|
||||
output->output = wl_registry_bind(registry, name,
|
||||
&wl_output_interface, 4);
|
||||
output->state = state;
|
||||
output->scale = 1;
|
||||
|
||||
wl_output_set_user_data(output->output, output);
|
||||
wl_output_add_listener(output->output, &output_listener, output);
|
||||
}
|
||||
}
|
||||
|
||||
void surface_enter(void *data, struct wl_surface *surface, struct wl_output *wl_output) {
|
||||
struct state *state = data;
|
||||
state->output = wl_output_get_user_data(wl_output);
|
||||
|
||||
match();
|
||||
draw_sf(state);
|
||||
}
|
||||
|
||||
int roundtrip(struct state *state) {
|
||||
if (wl_display_roundtrip(state->display)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this function returns 1, something went wrong.
|
||||
* This may be that the user is using X11, or a compositor like Mutter.
|
||||
* In this case, it may be a good idea to fall back to X11.
|
||||
*/
|
||||
int init_disp(struct state *state) {
|
||||
state->display = wl_display_connect(NULL);
|
||||
|
||||
// Open display
|
||||
if (!state->display) {
|
||||
return 1;
|
||||
} else {
|
||||
no_display = 0;
|
||||
}
|
||||
|
||||
struct wl_registry *registry = wl_display_get_registry(state->display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, state);
|
||||
wl_display_roundtrip(state->display);
|
||||
|
||||
assert(state->compositor != NULL);
|
||||
assert(state->layer_shell != NULL);
|
||||
assert(state->shm != NULL);
|
||||
|
||||
wl_display_roundtrip(state->display);
|
||||
|
||||
if (state->output_name && !state->output) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void resizeclient_wl(struct state *state) {
|
||||
struct item *item;
|
||||
int omh = mh;
|
||||
int ic = 0;
|
||||
|
||||
// walk through all items
|
||||
for (item = items; item && item->text; item++)
|
||||
ic++;
|
||||
|
||||
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight);
|
||||
lines = MIN(ic, MAX(lines, 0));
|
||||
reallines = lines;
|
||||
mh = (lines + 1) * bh + 2 * menumarginv;
|
||||
|
||||
if (mh == omh) {
|
||||
return;
|
||||
}
|
||||
|
||||
// why have an empty line? when there's nothing to draw there anyway?
|
||||
if (hideprompt && hideinput && hidemode && hidematchcount)
|
||||
mh += bh;
|
||||
|
||||
state->width = mw;
|
||||
state->height = mh;
|
||||
|
||||
state->buffer = create_buffer(state);
|
||||
|
||||
if (drw == NULL) {
|
||||
die("spmenu: drw == NULL");
|
||||
}
|
||||
|
||||
if (state->buffer == NULL) {
|
||||
die("state->buffer == null");
|
||||
}
|
||||
|
||||
drw_create_surface_wl(drw, state->data, state->width, state->height);
|
||||
|
||||
set_layer_size(state, state->width, state->height);
|
||||
wl_surface_set_buffer_scale(state->surface, 1);
|
||||
wl_surface_attach(state->surface, state->buffer, 0, 0);
|
||||
wl_surface_damage(state->surface, 0, 0, state->width, state->height);
|
||||
wl_surface_commit(state->surface);
|
||||
}
|
||||
|
||||
/* It is advised you call this function right before calling init_disp()
|
||||
* It sets up keybinds for you.
|
||||
*/
|
||||
int init_keys(struct state *state) {
|
||||
state->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
if (!state->xkb_context) {
|
||||
return 1;
|
||||
} else {
|
||||
has_keys = 1;
|
||||
}
|
||||
|
||||
state->timer = timerfd_create(CLOCK_MONOTONIC, 0);
|
||||
|
||||
if (state->timer < 0) {
|
||||
has_keys = 0;
|
||||
fprintf(stderr, "timerfd_create() failed\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_layer(struct state *state, char *name) {
|
||||
assert(state->compositor != NULL);
|
||||
|
||||
state->surface = wl_compositor_create_surface(state->compositor);
|
||||
|
||||
assert(state->surface != NULL);
|
||||
assert(state->layer_shell != NULL);
|
||||
|
||||
wl_surface_add_listener(state->surface, &surface_listener, state);
|
||||
state->layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
||||
state->layer_shell,
|
||||
state->surface,
|
||||
NULL,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||
name);
|
||||
|
||||
assert(state->layer_surface != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int anchor_layer(struct state *state, int position) {
|
||||
assert(state->layer_surface != NULL);
|
||||
zwlr_layer_surface_v1_set_anchor(
|
||||
state->layer_surface,
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT |
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT |
|
||||
(position == 0 ? ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM :
|
||||
position == 1 ? ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP :
|
||||
0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_layer_size(struct state *state, int32_t width, int32_t height) {
|
||||
assert(state->layer_surface != NULL);
|
||||
|
||||
zwlr_layer_surface_v1_set_size(state->layer_surface, width, height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_exclusive_zone(struct state *state, unsigned int val) {
|
||||
assert(state->layer_surface != NULL);
|
||||
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(state->layer_surface, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_keyboard(struct state *state, int interactivity) {
|
||||
assert(state->layer_surface != NULL);
|
||||
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(state->layer_surface, interactivity ? true : false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_layer_listener(struct state *state) {
|
||||
assert(state->layer_surface != NULL);
|
||||
|
||||
zwlr_layer_surface_v1_add_listener(state->layer_surface, &layer_surface_listener, state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_visible_layer(struct state *state) {
|
||||
assert(state->layer_surface != NULL);
|
||||
assert(state->surface != NULL);
|
||||
|
||||
wl_surface_commit(state->surface);
|
||||
|
||||
return 0;
|
||||
}
|
204
libs/wl/wayland.h
Normal file
204
libs/wl/wayland.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <time.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <poll.h>
|
||||
#include <wayland-client.h>
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "xdg-shell-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
|
||||
struct output {
|
||||
struct state *state;
|
||||
struct wl_output *output;
|
||||
|
||||
int32_t scale;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned int mode;
|
||||
char *modifier;
|
||||
xkb_keysym_t keysym;
|
||||
void (*func)(Arg *);
|
||||
Arg arg;
|
||||
} WlKey;
|
||||
|
||||
static WlKey wl_ckeys[256];
|
||||
static Mouse wl_cbuttons[256];
|
||||
|
||||
#define WL_CtrlShift "CtrlShift"
|
||||
#define WL_CtrlShiftSuper "CtrlShiftSuper"
|
||||
#define WL_CtrlSuper "CtrlSuper"
|
||||
#define WL_CtrlAlt "CtrlAlt"
|
||||
#define WL_CtrlAltShift "CtrlAltShift"
|
||||
#define WL_CtrlAltShiftSuper "CtrlAltShiftSuper"
|
||||
#define WL_CtrlAltSuper "CtrlAltSuper"
|
||||
#define WL_AltShift "AltShift"
|
||||
#define WL_Shift "Shift"
|
||||
#define WL_Ctrl "Ctrl"
|
||||
#define WL_Alt "Alt"
|
||||
#define WL_Super "Super"
|
||||
#define WL_None "None"
|
||||
|
||||
#define WL_Left 0x110
|
||||
#define WL_Right 0x111
|
||||
#define WL_Middle 0x112
|
||||
#define WL_Side 0x113
|
||||
#define WL_Extra 0x114
|
||||
#define WL_Forward 0x115
|
||||
#define WL_Back 0x116
|
||||
#define WL_Task 0x117
|
||||
|
||||
static WlKey wlhkeys[1] = { { -1, WL_CtrlAlt, XKB_KEY_Delete, quit, {0} } };
|
||||
|
||||
struct state {
|
||||
struct output *output;
|
||||
char *output_name;
|
||||
|
||||
struct wl_display *display;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct wl_seat *seat;
|
||||
struct wl_keyboard *keyboard;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_surface *surface;
|
||||
|
||||
struct zwlr_layer_shell_v1 *layer_shell;
|
||||
struct zwlr_layer_surface_v1 *layer_surface;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* Taken from wmenu */
|
||||
int timer;
|
||||
int delay;
|
||||
int period;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
struct xkb_keymap *xkb_keymap;
|
||||
struct xkb_state *xkb_state;
|
||||
|
||||
enum wl_keyboard_key_state repeat_key_state;
|
||||
|
||||
xkb_keysym_t repeat_sym;
|
||||
|
||||
void *data;
|
||||
struct wl_buffer *buffer;
|
||||
};
|
||||
|
||||
struct state state = { 0 };
|
||||
|
||||
static int output_physical_width = 0;
|
||||
static int output_physical_height = 0;
|
||||
static int output_width = 0;
|
||||
static int output_height = 0;
|
||||
|
||||
static int mouse_x = 0;
|
||||
static int mouse_y = 0;
|
||||
|
||||
static void zero();
|
||||
static void resizeclient_wl(struct state *state);
|
||||
static void output_scale(void *data, struct wl_output *wl_output, int32_t factor);
|
||||
static void output_name(void *data, struct wl_output *wl_output, const char *name);
|
||||
static void output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t output_transform);
|
||||
static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh);
|
||||
static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height);
|
||||
static void layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface);
|
||||
static void draw_sf(struct state *state);
|
||||
static void global_handler(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version);
|
||||
static void seat_capabilities(void *data, struct wl_seat *seat, enum wl_seat_capability caps);
|
||||
static void surface_enter(void *data, struct wl_surface *surface, struct wl_output *wl_output);
|
||||
static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size);
|
||||
static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state);
|
||||
static void keyboard_modifiers(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group);
|
||||
static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay);
|
||||
static void keypress_wl(struct state *state, enum wl_keyboard_key_state key_state, xkb_keysym_t sym);
|
||||
static void pointer_button_handler(void *data, struct wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state);
|
||||
static void pointer_motion_handler(void *data, struct wl_pointer *pointer, uint32_t time, wl_fixed_t x, wl_fixed_t y);
|
||||
static void buttonpress_wl(uint32_t button, double ex, double ey);
|
||||
static int is_correct_modifier(struct state *state, char *modifier);
|
||||
static int roundtrip(struct state *state);
|
||||
static int init_disp(struct state *state);
|
||||
static int init_keys(struct state *state);
|
||||
static int create_layer(struct state *state, char *name);
|
||||
static int anchor_layer(struct state *state, int position);
|
||||
static int set_layer_size(struct state *state, int32_t width, int32_t height);
|
||||
static int set_exclusive_zone(struct state *state, unsigned int val);
|
||||
static int set_keyboard(struct state *state, int interactivity);
|
||||
static int add_layer_listener(struct state *state);
|
||||
static int set_visible_layer(struct state *state);
|
||||
|
||||
/* Set to 0 if the connection was successful
|
||||
* You can use this for say, X11 compatibility mode.
|
||||
*/
|
||||
static int no_display = 1;
|
||||
|
||||
/* Note that you MUST override this before calling create_layer() because
|
||||
* otherwise nothing will be drawn. Do not forget to do this.
|
||||
*/
|
||||
static int allow_draw = 0;
|
||||
|
||||
/* Set automatically */
|
||||
static int has_keys = 0;
|
||||
|
||||
/* See global_handler */
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = global_handler,
|
||||
.global_remove = zero,
|
||||
};
|
||||
|
||||
/* See surface_enter */
|
||||
static const struct wl_surface_listener surface_listener = {
|
||||
.enter = surface_enter,
|
||||
.leave = zero,
|
||||
};
|
||||
|
||||
static const struct wl_keyboard_listener keyboard_listener = {
|
||||
.keymap = keyboard_keymap,
|
||||
.enter = zero,
|
||||
.leave = zero,
|
||||
.key = keyboard_key,
|
||||
.modifiers = keyboard_modifiers,
|
||||
.repeat_info = keyboard_repeat_info,
|
||||
};
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
.enter = zero,
|
||||
.leave = zero,
|
||||
.motion = pointer_motion_handler,
|
||||
.button = pointer_button_handler,
|
||||
.axis = zero,
|
||||
};
|
||||
|
||||
struct wl_output_listener output_listener = {
|
||||
.geometry = output_geometry,
|
||||
.mode = output_mode,
|
||||
.done = zero,
|
||||
.scale = output_scale,
|
||||
.name = output_name,
|
||||
.description = zero,
|
||||
};
|
||||
|
||||
struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||
.configure = layer_surface_configure,
|
||||
.closed = layer_surface_closed,
|
||||
};
|
||||
|
||||
struct wl_seat_listener seat_listener = {
|
||||
.capabilities = seat_capabilities,
|
||||
.name = zero,
|
||||
};
|
||||
|
||||
static const struct wl_buffer_listener buffer_listener = {
|
||||
.release = zero,
|
||||
};
|
563
libs/wl/wlr-layer-shell-unstable-v1-client-protocol.h
Normal file
563
libs/wl/wlr-layer-shell-unstable-v1-client-protocol.h
Normal file
|
@ -0,0 +1,563 @@
|
|||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
#ifndef WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_wlr_layer_shell_unstable_v1 The wlr_layer_shell_unstable_v1 protocol
|
||||
* @section page_ifaces_wlr_layer_shell_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zwlr_layer_shell_v1 - create surfaces that are layers of the desktop
|
||||
* - @subpage page_iface_zwlr_layer_surface_v1 - layer metadata interface
|
||||
* @section page_copyright_wlr_layer_shell_unstable_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* Copyright © 2017 Drew DeVault
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
* </pre>
|
||||
*/
|
||||
struct wl_output;
|
||||
struct wl_surface;
|
||||
struct xdg_popup;
|
||||
struct zwlr_layer_shell_v1;
|
||||
struct zwlr_layer_surface_v1;
|
||||
|
||||
#ifndef ZWLR_LAYER_SHELL_V1_INTERFACE
|
||||
#define ZWLR_LAYER_SHELL_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zwlr_layer_shell_v1 zwlr_layer_shell_v1
|
||||
* @section page_iface_zwlr_layer_shell_v1_desc Description
|
||||
*
|
||||
* Clients can use this interface to assign the surface_layer role to
|
||||
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
* rendered with a defined z-depth respective to each other. They may also be
|
||||
* anchored to the edges and corners of a screen and specify input handling
|
||||
* semantics. This interface should be suitable for the implementation of
|
||||
* many desktop shell components, and a broad number of other applications
|
||||
* that interact with the desktop.
|
||||
* @section page_iface_zwlr_layer_shell_v1_api API
|
||||
* See @ref iface_zwlr_layer_shell_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zwlr_layer_shell_v1 The zwlr_layer_shell_v1 interface
|
||||
*
|
||||
* Clients can use this interface to assign the surface_layer role to
|
||||
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
* rendered with a defined z-depth respective to each other. They may also be
|
||||
* anchored to the edges and corners of a screen and specify input handling
|
||||
* semantics. This interface should be suitable for the implementation of
|
||||
* many desktop shell components, and a broad number of other applications
|
||||
* that interact with the desktop.
|
||||
*/
|
||||
extern const struct wl_interface zwlr_layer_shell_v1_interface;
|
||||
#endif
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_INTERFACE
|
||||
#define ZWLR_LAYER_SURFACE_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zwlr_layer_surface_v1 zwlr_layer_surface_v1
|
||||
* @section page_iface_zwlr_layer_surface_v1_desc Description
|
||||
*
|
||||
* An interface that may be implemented by a wl_surface, for surfaces that
|
||||
* are designed to be rendered as a layer of a stacked desktop-like
|
||||
* environment.
|
||||
*
|
||||
* Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||
* is double-buffered, and will be applied at the time wl_surface.commit of
|
||||
* the corresponding wl_surface is called.
|
||||
* @section page_iface_zwlr_layer_surface_v1_api API
|
||||
* See @ref iface_zwlr_layer_surface_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zwlr_layer_surface_v1 The zwlr_layer_surface_v1 interface
|
||||
*
|
||||
* An interface that may be implemented by a wl_surface, for surfaces that
|
||||
* are designed to be rendered as a layer of a stacked desktop-like
|
||||
* environment.
|
||||
*
|
||||
* Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||
* is double-buffered, and will be applied at the time wl_surface.commit of
|
||||
* the corresponding wl_surface is called.
|
||||
*/
|
||||
extern const struct wl_interface zwlr_layer_surface_v1_interface;
|
||||
#endif
|
||||
|
||||
#ifndef ZWLR_LAYER_SHELL_V1_ERROR_ENUM
|
||||
#define ZWLR_LAYER_SHELL_V1_ERROR_ENUM
|
||||
enum zwlr_layer_shell_v1_error {
|
||||
/**
|
||||
* wl_surface has another role
|
||||
*/
|
||||
ZWLR_LAYER_SHELL_V1_ERROR_ROLE = 0,
|
||||
/**
|
||||
* layer value is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER = 1,
|
||||
/**
|
||||
* wl_surface has a buffer attached or committed
|
||||
*/
|
||||
ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED = 2,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SHELL_V1_ERROR_ENUM */
|
||||
|
||||
#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||
#define ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
* available layers for surfaces
|
||||
*
|
||||
* These values indicate which layers a surface can be rendered in. They
|
||||
* are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||
* will typically be rendered between the bottom and top layers.
|
||||
* Fullscreen shell surfaces are typically rendered at the top layer.
|
||||
* Multiple surfaces can share a single layer, and ordering within a
|
||||
* single layer is undefined.
|
||||
*/
|
||||
enum zwlr_layer_shell_v1_layer {
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND = 0,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM = 1,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_TOP = 2,
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY = 3,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SHELL_V1_LAYER_ENUM */
|
||||
|
||||
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE 0
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||
static inline void
|
||||
zwlr_layer_shell_v1_set_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_shell_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||
static inline void *
|
||||
zwlr_layer_shell_v1_get_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zwlr_layer_shell_v1_get_version(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||
static inline void
|
||||
zwlr_layer_shell_v1_destroy(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||
{
|
||||
wl_proxy_destroy((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_shell_v1
|
||||
*
|
||||
* Create a layer surface for an existing surface. This assigns the role of
|
||||
* layer_surface, or raises a protocol error if another role is already
|
||||
* assigned.
|
||||
*
|
||||
* Creating a layer surface from a wl_surface which has a buffer attached
|
||||
* or committed is a client error, and any attempts by a client to attach
|
||||
* or manipulate a buffer prior to the first layer_surface.configure call
|
||||
* must also be treated as errors.
|
||||
*
|
||||
* You may pass NULL for output to allow the compositor to decide which
|
||||
* output to use. Generally this will be the one that the user most
|
||||
* recently interacted with.
|
||||
*
|
||||
* Clients can specify a namespace that defines the purpose of the layer
|
||||
* surface.
|
||||
*/
|
||||
static inline struct zwlr_layer_surface_v1 *
|
||||
zwlr_layer_shell_v1_get_layer_surface(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, struct wl_surface *surface, struct wl_output *output, uint32_t layer, const char *namespace)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_shell_v1,
|
||||
ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE, &zwlr_layer_surface_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1), 0, NULL, surface, output, layer, namespace);
|
||||
|
||||
return (struct zwlr_layer_surface_v1 *) id;
|
||||
}
|
||||
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
|
||||
#define ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
|
||||
enum zwlr_layer_surface_v1_error {
|
||||
/**
|
||||
* provided surface state is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SURFACE_STATE = 0,
|
||||
/**
|
||||
* size is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE = 1,
|
||||
/**
|
||||
* anchor bitfield is invalid
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_ANCHOR = 2,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SURFACE_V1_ERROR_ENUM */
|
||||
|
||||
#ifndef ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
|
||||
#define ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
|
||||
enum zwlr_layer_surface_v1_anchor {
|
||||
/**
|
||||
* the top edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP = 1,
|
||||
/**
|
||||
* the bottom edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM = 2,
|
||||
/**
|
||||
* the left edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT = 4,
|
||||
/**
|
||||
* the right edge of the anchor rectangle
|
||||
*/
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT = 8,
|
||||
};
|
||||
#endif /* ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM */
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
* @struct zwlr_layer_surface_v1_listener
|
||||
*/
|
||||
struct zwlr_layer_surface_v1_listener {
|
||||
/**
|
||||
* suggest a surface change
|
||||
*
|
||||
* The configure event asks the client to resize its surface.
|
||||
*
|
||||
* Clients should arrange their surface for the new states, and
|
||||
* then send an ack_configure request with the serial sent in this
|
||||
* configure event at some point before committing the new surface.
|
||||
*
|
||||
* The client is free to dismiss all but the last configure event
|
||||
* it received.
|
||||
*
|
||||
* The width and height arguments specify the size of the window in
|
||||
* surface-local coordinates.
|
||||
*
|
||||
* The size is a hint, in the sense that the client is free to
|
||||
* ignore it if it doesn't resize, pick a smaller size (to satisfy
|
||||
* aspect ratio or resize in steps of NxM pixels). If the client
|
||||
* picks a smaller size and is anchored to two opposite anchors
|
||||
* (e.g. 'top' and 'bottom'), the surface will be centered on this
|
||||
* axis.
|
||||
*
|
||||
* If the width or height arguments are zero, it means the client
|
||||
* should decide its own window dimension.
|
||||
*/
|
||||
void (*configure)(void *data,
|
||||
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
|
||||
uint32_t serial,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
/**
|
||||
* surface should be closed
|
||||
*
|
||||
* The closed event is sent by the compositor when the surface
|
||||
* will no longer be shown. The output may have been destroyed or
|
||||
* the user may have asked for it to be removed. Further changes to
|
||||
* the surface will be ignored. The client should destroy the
|
||||
* resource after receiving this event, and create a new surface if
|
||||
* they so choose.
|
||||
*/
|
||||
void (*closed)(void *data,
|
||||
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
static inline int
|
||||
zwlr_layer_surface_v1_add_listener(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
|
||||
const struct zwlr_layer_surface_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE 0
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR 1
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE 2
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN 3
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY 4
|
||||
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP 5
|
||||
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE 6
|
||||
#define ZWLR_LAYER_SURFACE_V1_DESTROY 7
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_CONFIGURE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_CLOSED_SINCE_VERSION 1
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*/
|
||||
#define ZWLR_LAYER_SURFACE_V1_DESTROY_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zwlr_layer_surface_v1 */
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_surface_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zwlr_layer_surface_v1 */
|
||||
static inline void *
|
||||
zwlr_layer_surface_v1_get_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zwlr_layer_surface_v1_get_version(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Sets the size of the surface in surface-local coordinates. The
|
||||
* compositor will display the surface centered with respect to its
|
||||
* anchors.
|
||||
*
|
||||
* If you pass 0 for either value, the compositor will assign it and
|
||||
* inform you of the assignment in the configure event. You must set your
|
||||
* anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||
* protocol error. Both values are 0 by default.
|
||||
*
|
||||
* Size is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_size(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t width, uint32_t height)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_SIZE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Requests that the compositor anchor the surface to the specified edges
|
||||
* and corners. If two orthoginal edges are specified (e.g. 'top' and
|
||||
* 'left'), then the anchor point will be the intersection of the edges
|
||||
* (e.g. the top left corner of the output); otherwise the anchor point
|
||||
* will be centered on that edge, or in the center if none is specified.
|
||||
*
|
||||
* Anchor is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_anchor(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t anchor)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_ANCHOR, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, anchor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Requests that the compositor avoids occluding an area of the surface
|
||||
* with other surfaces. The compositor's use of this information is
|
||||
* implementation-dependent - do not assume that this region will not
|
||||
* actually be occluded.
|
||||
*
|
||||
* A positive value is only meaningful if the surface is anchored to an
|
||||
* edge, rather than a corner. The zone is the number of surface-local
|
||||
* coordinates from the edge that are considered exclusive.
|
||||
*
|
||||
* Surfaces that do not wish to have an exclusive zone may instead specify
|
||||
* how they should interact with surfaces that do. If set to zero, the
|
||||
* surface indicates that it would like to be moved to avoid occluding
|
||||
* surfaces with a positive excluzive zone. If set to -1, the surface
|
||||
* indicates that it would not like to be moved to accommodate for other
|
||||
* surfaces, and the compositor should extend it all the way to the edges
|
||||
* it is anchored to.
|
||||
*
|
||||
* For example, a panel might set its exclusive zone to 10, so that
|
||||
* maximized shell surfaces are not shown on top of it. A notification
|
||||
* might set its exclusive zone to 0, so that it is moved to avoid
|
||||
* occluding the panel, but shell surfaces are shown underneath it. A
|
||||
* wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||
* they stretch below or over the panel.
|
||||
*
|
||||
* The default value is 0.
|
||||
*
|
||||
* Exclusive zone is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_exclusive_zone(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t zone)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, zone);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Requests that the surface be placed some distance away from the anchor
|
||||
* point on the output, in surface-local coordinates. Setting this value
|
||||
* for edges you are not anchored to has no effect.
|
||||
*
|
||||
* The exclusive zone includes the margin.
|
||||
*
|
||||
* Margin is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_margin(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t top, int32_t right, int32_t bottom, int32_t left)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_MARGIN, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, top, right, bottom, left);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* Set to 1 to request that the seat send keyboard events to this layer
|
||||
* surface. For layers below the shell surface layer, the seat will use
|
||||
* normal focus semantics. For layers above the shell surface layers, the
|
||||
* seat will always give exclusive keyboard focus to the top-most layer
|
||||
* which has keyboard interactivity set to true.
|
||||
*
|
||||
* Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
* you do not want to receive them, set the input region on your surface
|
||||
* to an empty region.
|
||||
*
|
||||
* Events is double-buffered, see wl_surface.commit.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_set_keyboard_interactivity(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t keyboard_interactivity)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, keyboard_interactivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||
* should have been created via xdg_surface::get_popup with the parent set
|
||||
* to NULL, and this request must be invoked before committing the popup's
|
||||
* initial state.
|
||||
*
|
||||
* See the documentation of xdg_popup for more details about what an
|
||||
* xdg_popup is and how it is used.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_get_popup(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, struct xdg_popup *popup)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_GET_POPUP, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, popup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* When a configure event is received, if a client commits the
|
||||
* surface in response to the configure event, then the client
|
||||
* must make an ack_configure request sometime before the commit
|
||||
* request, passing along the serial of the configure event.
|
||||
*
|
||||
* If the client receives multiple configure events before it
|
||||
* can respond to one, it only has to ack the last configure event.
|
||||
*
|
||||
* A client is not required to commit immediately after sending
|
||||
* an ack_configure request - it may even ack_configure several times
|
||||
* before its next surface commit.
|
||||
*
|
||||
* A client may send multiple ack_configure requests before committing, but
|
||||
* only the last request sent before a commit indicates which configure
|
||||
* event the client really is responding to.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_ack_configure(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), 0, serial);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zwlr_layer_surface_v1
|
||||
*
|
||||
* This request destroys the layer surface.
|
||||
*/
|
||||
static inline void
|
||||
zwlr_layer_surface_v1_destroy(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||
ZWLR_LAYER_SURFACE_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
81
libs/wl/wlr-layer-shell-unstable-v1-protocol.c
Normal file
81
libs/wl/wlr-layer-shell-unstable-v1-protocol.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2017 Drew DeVault
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this
|
||||
* software and its documentation for any purpose is hereby granted
|
||||
* without fee, provided that the above copyright notice appear in
|
||||
* all copies and that both that copyright notice and this permission
|
||||
* notice appear in supporting documentation, and that the name of
|
||||
* the copyright holders not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface zwlr_layer_surface_v1_interface;
|
||||
|
||||
static const struct wl_interface *wlr_layer_shell_unstable_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&zwlr_layer_surface_v1_interface,
|
||||
&wl_surface_interface,
|
||||
&wl_output_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_popup_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message zwlr_layer_shell_v1_requests[] = {
|
||||
{ "get_layer_surface", "no?ous", wlr_layer_shell_unstable_v1_types + 4 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface zwlr_layer_shell_v1_interface = {
|
||||
"zwlr_layer_shell_v1", 1,
|
||||
1, zwlr_layer_shell_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message zwlr_layer_surface_v1_requests[] = {
|
||||
{ "set_size", "uu", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_anchor", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_exclusive_zone", "i", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_margin", "iiii", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "set_keyboard_interactivity", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "get_popup", "o", wlr_layer_shell_unstable_v1_types + 9 },
|
||||
{ "ack_configure", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "destroy", "", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message zwlr_layer_surface_v1_events[] = {
|
||||
{ "configure", "uuu", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
{ "closed", "", wlr_layer_shell_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface zwlr_layer_surface_v1_interface = {
|
||||
"zwlr_layer_surface_v1", 1,
|
||||
8, zwlr_layer_surface_v1_requests,
|
||||
2, zwlr_layer_surface_v1_events,
|
||||
};
|
||||
|
414
libs/wl/xdg-output-unstable-v1-client-protocol.h
Normal file
414
libs/wl/xdg-output-unstable-v1-client-protocol.h
Normal file
|
@ -0,0 +1,414 @@
|
|||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
#ifndef XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
#define XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "wayland-client.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol
|
||||
* Protocol to describe output regions
|
||||
*
|
||||
* @section page_desc_xdg_output_unstable_v1 Description
|
||||
*
|
||||
* This protocol aims at describing outputs in a way which is more in line
|
||||
* with the concept of an output on desktop oriented systems.
|
||||
*
|
||||
* Some information are more specific to the concept of an output for
|
||||
* a desktop oriented system and may not make sense in other applications,
|
||||
* such as IVI systems for example.
|
||||
*
|
||||
* Typically, the global compositor space on a desktop system is made of
|
||||
* a contiguous or overlapping set of rectangular regions.
|
||||
*
|
||||
* The logical_position and logical_size events defined in this protocol
|
||||
* might provide information identical to their counterparts already
|
||||
* available from wl_output, in which case the information provided by this
|
||||
* protocol should be preferred to their equivalent in wl_output. The goal is
|
||||
* to move the desktop specific concepts (such as output location within the
|
||||
* global compositor space, etc.) out of the core wl_output protocol.
|
||||
*
|
||||
* Warning! The protocol described in this file is experimental and
|
||||
* backward incompatible changes may be made. Backward compatible
|
||||
* changes may be added together with the corresponding interface
|
||||
* version bump.
|
||||
* Backward incompatible changes are done by bumping the version
|
||||
* number in the protocol and interface names and resetting the
|
||||
* interface version. Once the protocol is to be declared stable,
|
||||
* the 'z' prefix and the version number in the protocol and
|
||||
* interface names are removed and the interface version number is
|
||||
* reset.
|
||||
*
|
||||
* @section page_ifaces_xdg_output_unstable_v1 Interfaces
|
||||
* - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects
|
||||
* - @subpage page_iface_zxdg_output_v1 - compositor logical output region
|
||||
* @section page_copyright_xdg_output_unstable_v1 Copyright
|
||||
* <pre>
|
||||
*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
* </pre>
|
||||
*/
|
||||
struct wl_output;
|
||||
struct zxdg_output_manager_v1;
|
||||
struct zxdg_output_v1;
|
||||
|
||||
#ifndef ZXDG_OUTPUT_MANAGER_V1_INTERFACE
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1
|
||||
* @section page_iface_zxdg_output_manager_v1_desc Description
|
||||
*
|
||||
* A global factory interface for xdg_output objects.
|
||||
* @section page_iface_zxdg_output_manager_v1_api API
|
||||
* See @ref iface_zxdg_output_manager_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface
|
||||
*
|
||||
* A global factory interface for xdg_output objects.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_output_manager_v1_interface;
|
||||
#endif
|
||||
#ifndef ZXDG_OUTPUT_V1_INTERFACE
|
||||
#define ZXDG_OUTPUT_V1_INTERFACE
|
||||
/**
|
||||
* @page page_iface_zxdg_output_v1 zxdg_output_v1
|
||||
* @section page_iface_zxdg_output_v1_desc Description
|
||||
*
|
||||
* An xdg_output describes part of the compositor geometry.
|
||||
*
|
||||
* This typically corresponds to a monitor that displays part of the
|
||||
* compositor space.
|
||||
*
|
||||
* For objects version 3 onwards, after all xdg_output properties have been
|
||||
* sent (when the object is created and when properties are updated), a
|
||||
* wl_output.done event is sent. This allows changes to the output
|
||||
* properties to be seen as atomic, even if they happen via multiple events.
|
||||
* @section page_iface_zxdg_output_v1_api API
|
||||
* See @ref iface_zxdg_output_v1.
|
||||
*/
|
||||
/**
|
||||
* @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface
|
||||
*
|
||||
* An xdg_output describes part of the compositor geometry.
|
||||
*
|
||||
* This typically corresponds to a monitor that displays part of the
|
||||
* compositor space.
|
||||
*
|
||||
* For objects version 3 onwards, after all xdg_output properties have been
|
||||
* sent (when the object is created and when properties are updated), a
|
||||
* wl_output.done event is sent. This allows changes to the output
|
||||
* properties to be seen as atomic, even if they happen via multiple events.
|
||||
*/
|
||||
extern const struct wl_interface zxdg_output_v1_interface;
|
||||
#endif
|
||||
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zxdg_output_manager_v1 */
|
||||
static inline void
|
||||
zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zxdg_output_manager_v1 */
|
||||
static inline void *
|
||||
zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*
|
||||
* Using this request a client can tell the server that it is not
|
||||
* going to use the xdg_output_manager object anymore.
|
||||
*
|
||||
* Any objects already created through this instance are not affected.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1,
|
||||
ZXDG_OUTPUT_MANAGER_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_manager_v1
|
||||
*
|
||||
* This creates a new xdg_output object for the given wl_output.
|
||||
*/
|
||||
static inline struct zxdg_output_v1 *
|
||||
zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output)
|
||||
{
|
||||
struct wl_proxy *id;
|
||||
|
||||
id = wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_manager_v1,
|
||||
ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1), 0, NULL, output);
|
||||
|
||||
return (struct zxdg_output_v1 *) id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
* @struct zxdg_output_v1_listener
|
||||
*/
|
||||
struct zxdg_output_v1_listener {
|
||||
/**
|
||||
* position of the output within the global compositor space
|
||||
*
|
||||
* The position event describes the location of the wl_output
|
||||
* within the global compositor space.
|
||||
*
|
||||
* The logical_position event is sent after creating an xdg_output
|
||||
* (see xdg_output_manager.get_xdg_output) and whenever the
|
||||
* location of the output changes within the global compositor
|
||||
* space.
|
||||
* @param x x position within the global compositor space
|
||||
* @param y y position within the global compositor space
|
||||
*/
|
||||
void (*logical_position)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
int32_t x,
|
||||
int32_t y);
|
||||
/**
|
||||
* size of the output in the global compositor space
|
||||
*
|
||||
* The logical_size event describes the size of the output in the
|
||||
* global compositor space.
|
||||
*
|
||||
* Most regular Wayland clients should not pay attention to the
|
||||
* logical size and would rather rely on xdg_shell interfaces.
|
||||
*
|
||||
* Some clients such as Xwayland, however, need this to configure
|
||||
* their surfaces in the global compositor space as the compositor
|
||||
* may apply a different scale from what is advertised by the
|
||||
* output scaling property (to achieve fractional scaling, for
|
||||
* example).
|
||||
*
|
||||
* For example, for a wl_output mode 3840×2160 and a scale factor
|
||||
* 2:
|
||||
*
|
||||
* - A compositor not scaling the monitor viewport in its
|
||||
* compositing space will advertise a logical size of 3840×2160,
|
||||
*
|
||||
* - A compositor scaling the monitor viewport with scale factor 2
|
||||
* will advertise a logical size of 1920×1080,
|
||||
*
|
||||
* - A compositor scaling the monitor viewport using a fractional
|
||||
* scale of 1.5 will advertise a logical size of 2560×1440.
|
||||
*
|
||||
* For example, for a wl_output mode 1920×1080 and a 90 degree
|
||||
* rotation, the compositor will advertise a logical size of
|
||||
* 1080x1920.
|
||||
*
|
||||
* The logical_size event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output) and whenever the logical size
|
||||
* of the output changes, either as a result of a change in the
|
||||
* applied scale or because of a change in the corresponding output
|
||||
* mode(see wl_output.mode) or transform (see wl_output.transform).
|
||||
* @param width width in global compositor space
|
||||
* @param height height in global compositor space
|
||||
*/
|
||||
void (*logical_size)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
/**
|
||||
* all information about the output have been sent
|
||||
*
|
||||
* This event is sent after all other properties of an xdg_output
|
||||
* have been sent.
|
||||
*
|
||||
* This allows changes to the xdg_output properties to be seen as
|
||||
* atomic, even if they happen via multiple events.
|
||||
*
|
||||
* For objects version 3 onwards, this event is deprecated.
|
||||
* Compositors are not required to send it anymore and must send
|
||||
* wl_output.done instead.
|
||||
*/
|
||||
void (*done)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1);
|
||||
/**
|
||||
* name of this output
|
||||
*
|
||||
* Many compositors will assign names to their outputs, show them
|
||||
* to the user, allow them to be configured by name, etc. The
|
||||
* client may wish to know this name as well to offer the user
|
||||
* similar behaviors.
|
||||
*
|
||||
* The naming convention is compositor defined, but limited to
|
||||
* alphanumeric characters and dashes (-). Each name is unique
|
||||
* among all wl_output globals, but if a wl_output global is
|
||||
* destroyed the same name may be reused later. The names will also
|
||||
* remain consistent across sessions with the same hardware and
|
||||
* software configuration.
|
||||
*
|
||||
* Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc.
|
||||
* However, do not assume that the name is a reflection of an
|
||||
* underlying DRM connector, X11 connection, etc.
|
||||
*
|
||||
* The name event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output). This event is only sent once
|
||||
* per xdg_output, and the name does not change over the lifetime
|
||||
* of the wl_output global.
|
||||
*
|
||||
* This event is deprecated, instead clients should use
|
||||
* wl_output.name. Compositors must still support this event.
|
||||
* @param name output name
|
||||
* @since 2
|
||||
*/
|
||||
void (*name)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const char *name);
|
||||
/**
|
||||
* human-readable description of this output
|
||||
*
|
||||
* Many compositors can produce human-readable descriptions of
|
||||
* their outputs. The client may wish to know this description as
|
||||
* well, to communicate the user for various purposes.
|
||||
*
|
||||
* The description is a UTF-8 string with no convention defined for
|
||||
* its contents. Examples might include 'Foocorp 11" Display' or
|
||||
* 'Virtual X11 output via :1'.
|
||||
*
|
||||
* The description event is sent after creating an xdg_output (see
|
||||
* xdg_output_manager.get_xdg_output) and whenever the description
|
||||
* changes. The description is optional, and may not be sent at
|
||||
* all.
|
||||
*
|
||||
* For objects of version 2 and lower, this event is only sent once
|
||||
* per xdg_output, and the description does not change over the
|
||||
* lifetime of the wl_output global.
|
||||
*
|
||||
* This event is deprecated, instead clients should use
|
||||
* wl_output.description. Compositors must still support this
|
||||
* event.
|
||||
* @param description output description
|
||||
* @since 2
|
||||
*/
|
||||
void (*description)(void *data,
|
||||
struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const char *description);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
static inline int
|
||||
zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1,
|
||||
const struct zxdg_output_v1_listener *listener, void *data)
|
||||
{
|
||||
return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1,
|
||||
(void (**)(void)) listener, data);
|
||||
}
|
||||
|
||||
#define ZXDG_OUTPUT_V1_DESTROY 0
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*/
|
||||
#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1
|
||||
|
||||
/** @ingroup iface_zxdg_output_v1 */
|
||||
static inline void
|
||||
zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data)
|
||||
{
|
||||
wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data);
|
||||
}
|
||||
|
||||
/** @ingroup iface_zxdg_output_v1 */
|
||||
static inline void *
|
||||
zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
{
|
||||
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
{
|
||||
return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup iface_zxdg_output_v1
|
||||
*
|
||||
* Using this request a client can tell the server that it is not
|
||||
* going to use the xdg_output object anymore.
|
||||
*/
|
||||
static inline void
|
||||
zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1)
|
||||
{
|
||||
wl_proxy_marshal_flags((struct wl_proxy *) zxdg_output_v1,
|
||||
ZXDG_OUTPUT_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1), WL_MARSHAL_FLAG_DESTROY);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
68
libs/wl/xdg-output-unstable-v1-protocol.c
Normal file
68
libs/wl/xdg-output-unstable-v1-protocol.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface zxdg_output_v1_interface;
|
||||
|
||||
static const struct wl_interface *xdg_output_unstable_v1_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
&zxdg_output_v1_interface,
|
||||
&wl_output_interface,
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_manager_v1_requests[] = {
|
||||
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||
{ "get_xdg_output", "no", xdg_output_unstable_v1_types + 2 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface zxdg_output_manager_v1_interface = {
|
||||
"zxdg_output_manager_v1", 3,
|
||||
2, zxdg_output_manager_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_v1_requests[] = {
|
||||
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message zxdg_output_v1_events[] = {
|
||||
{ "logical_position", "ii", xdg_output_unstable_v1_types + 0 },
|
||||
{ "logical_size", "ii", xdg_output_unstable_v1_types + 0 },
|
||||
{ "done", "", xdg_output_unstable_v1_types + 0 },
|
||||
{ "name", "2s", xdg_output_unstable_v1_types + 0 },
|
||||
{ "description", "2s", xdg_output_unstable_v1_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface zxdg_output_v1_interface = {
|
||||
"zxdg_output_v1", 3,
|
||||
1, zxdg_output_v1_requests,
|
||||
5, zxdg_output_v1_events,
|
||||
};
|
||||
|
2290
libs/wl/xdg-shell-client-protocol.h
Normal file
2290
libs/wl/xdg-shell-client-protocol.h
Normal file
File diff suppressed because it is too large
Load diff
173
libs/wl/xdg-shell-protocol.c
Normal file
173
libs/wl/xdg-shell-protocol.c
Normal file
|
@ -0,0 +1,173 @@
|
|||
/* Generated by wayland-scanner 1.22.0 */
|
||||
|
||||
/*
|
||||
* Copyright © 2008-2013 Kristian Høgsberg
|
||||
* Copyright © 2013 Rafael Antognolli
|
||||
* Copyright © 2013 Jasper St. Pierre
|
||||
* Copyright © 2010-2013 Intel Corporation
|
||||
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||
* Copyright © 2015-2017 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "wayland-util.h"
|
||||
|
||||
extern const struct wl_interface wl_output_interface;
|
||||
extern const struct wl_interface wl_seat_interface;
|
||||
extern const struct wl_interface wl_surface_interface;
|
||||
extern const struct wl_interface xdg_popup_interface;
|
||||
extern const struct wl_interface xdg_positioner_interface;
|
||||
extern const struct wl_interface xdg_surface_interface;
|
||||
extern const struct wl_interface xdg_toplevel_interface;
|
||||
|
||||
static const struct wl_interface *xdg_shell_types[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_surface_interface,
|
||||
&wl_surface_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&xdg_popup_interface,
|
||||
&xdg_surface_interface,
|
||||
&xdg_positioner_interface,
|
||||
&xdg_toplevel_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
NULL,
|
||||
&wl_output_interface,
|
||||
&wl_seat_interface,
|
||||
NULL,
|
||||
&xdg_positioner_interface,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||
{ "pong", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_wm_base_events[] = {
|
||||
{ "ping", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface xdg_wm_base_interface = {
|
||||
"xdg_wm_base", 5,
|
||||
4, xdg_wm_base_requests,
|
||||
1, xdg_wm_base_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_positioner_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface xdg_positioner_interface = {
|
||||
"xdg_positioner", 5,
|
||||
10, xdg_positioner_requests,
|
||||
0, NULL,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_surface_events[] = {
|
||||
{ "configure", "u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface xdg_surface_interface = {
|
||||
"xdg_surface", 5,
|
||||
5, xdg_surface_requests,
|
||||
1, xdg_surface_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||
{ "set_title", "s", xdg_shell_types + 0 },
|
||||
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||
{ "move", "ou", xdg_shell_types + 16 },
|
||||
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_toplevel_events[] = {
|
||||
{ "configure", "iia", xdg_shell_types + 0 },
|
||||
{ "close", "", xdg_shell_types + 0 },
|
||||
{ "configure_bounds", "4ii", xdg_shell_types + 0 },
|
||||
{ "wm_capabilities", "5a", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface xdg_toplevel_interface = {
|
||||
"xdg_toplevel", 5,
|
||||
14, xdg_toplevel_requests,
|
||||
4, xdg_toplevel_events,
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_requests[] = {
|
||||
{ "destroy", "", xdg_shell_types + 0 },
|
||||
{ "grab", "ou", xdg_shell_types + 22 },
|
||||
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||
};
|
||||
|
||||
static const struct wl_message xdg_popup_events[] = {
|
||||
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||
{ "popup_done", "", xdg_shell_types + 0 },
|
||||
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||
};
|
||||
|
||||
WL_EXPORT const struct wl_interface xdg_popup_interface = {
|
||||
"xdg_popup", 5,
|
||||
3, xdg_popup_requests,
|
||||
3, xdg_popup_events,
|
||||
};
|
||||
|
|
@ -1,18 +1,13 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
void prepare_window_size(void) {
|
||||
// set horizontal and vertical padding
|
||||
sp = menupaddingh;
|
||||
vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
|
||||
void hexconv(const char *hex, unsigned short *r, unsigned short *g, unsigned short *b) {
|
||||
unsigned int col;
|
||||
|
||||
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight);
|
||||
lines = MAX(lines, 0);
|
||||
reallines = lines;
|
||||
sscanf(hex, "#%06X", &col);
|
||||
|
||||
lrpad = drw->font->h + textpadding;
|
||||
mh = (lines + 1) * bh + 2 * menumarginv; // lines + 1 * bh is the menu height
|
||||
|
||||
return;
|
||||
*r = (col >> 16) & 0xFF;
|
||||
*g = (col >> 8) & 0xFF;
|
||||
*b = col & 0xFF;
|
||||
}
|
||||
|
||||
void store_image_vars(void) {
|
||||
|
@ -22,7 +17,7 @@ void store_image_vars(void) {
|
|||
if (!imagew || !imageh || !imageg) {
|
||||
imagew = imagewidth;
|
||||
imageh = imageheight;
|
||||
imagegaps = imagegaps;
|
||||
imageg = imagegaps;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -46,28 +41,7 @@ void set_mode(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void get_width(int numwidthchecks, unsigned int minstrlen, unsigned int curstrlen) {
|
||||
struct item *item;
|
||||
unsigned int tmp = 0;
|
||||
|
||||
// get accurate width
|
||||
if (accuratewidth) {
|
||||
for (item = items; !lines && item && item->text; ++item) {
|
||||
curstrlen = strlen(item->text);
|
||||
if (numwidthchecks || minstrlen < curstrlen) {
|
||||
numwidthchecks = MAX(numwidthchecks - 1, 0);
|
||||
minstrlen = MAX(minstrlen, curstrlen);
|
||||
if ((tmp = MIN(TEXTW(item->text), mw/3) > inputw)) {
|
||||
inputw = tmp;
|
||||
if (tmp == mw/3)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void create_window(int x, int y, int w, int h) {
|
||||
void create_window_x11(int x, int y, int w, int h) {
|
||||
XSetWindowAttributes swa;
|
||||
|
||||
swa.override_redirect = managed ? False : True;
|
||||
|
@ -85,21 +59,35 @@ void create_window(int x, int y, int w, int h) {
|
|||
depth, InputOutput, visual,
|
||||
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void set_window(void) {
|
||||
void set_window_x11(void) {
|
||||
XColor col;
|
||||
XClassHint ch = { class, class };
|
||||
|
||||
unsigned short r;
|
||||
unsigned short g;
|
||||
unsigned short b;
|
||||
|
||||
hexconv(col_border, &r, &g, &b);
|
||||
|
||||
col.red = r << 8;
|
||||
col.green = g << 8;
|
||||
col.blue = b << 8;
|
||||
|
||||
if (!XAllocColor(dpy, cmap, &col)) {
|
||||
die("spmenu: failed to allocate xcolor");
|
||||
}
|
||||
|
||||
// set border and class
|
||||
XSetWindowBorder(dpy, win, scheme[SchemeBorder][ColBg].pixel);
|
||||
XSetWindowBorder(dpy, win, col.pixel);
|
||||
XSetClassHint(dpy, win, &ch);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void set_prop(void) {
|
||||
void set_prop_x11(void) {
|
||||
// set properties indicating what spmenu handles
|
||||
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
||||
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||
|
@ -112,7 +100,7 @@ void set_prop(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void resizeclient(void) {
|
||||
void resizeclient_x11(void) {
|
||||
int omh = mh;
|
||||
int x, y;
|
||||
#if USEXINERAMA
|
||||
|
@ -196,7 +184,7 @@ void resizeclient(void) {
|
|||
} else { // top or bottom
|
||||
x = 0;
|
||||
y = menuposition ? 0 : wa.height - mh - ypos;
|
||||
mw = wa.width;
|
||||
mw = (menuwidth > 0 ? menuwidth : wa.width);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
static void create_window(int x, int y, int w, int h);
|
||||
static void get_width(int numwidthchecks, unsigned int minstrlen, unsigned int curstrlen);
|
||||
static void prepare_window_size(void);
|
||||
static void set_window(void);
|
||||
static void set_prop(void);
|
||||
static void resizeclient(void);
|
||||
static void hexconv(const char *hex, unsigned short *r, unsigned short *g, unsigned short *b);
|
||||
static void create_window_x11(int x, int y, int w, int h);
|
||||
static void set_window_x11(void);
|
||||
static void set_prop_x11(void);
|
||||
static void resizeclient_x11(void);
|
||||
static void store_image_vars(void);
|
||||
static void set_mode(void);
|
||||
static void xinitvisual(void);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
void eventloop(void) {
|
||||
void eventloop_x11(void) {
|
||||
XEvent ev;
|
||||
int noimg = 0;
|
||||
|
||||
|
@ -14,7 +14,7 @@ void eventloop(void) {
|
|||
cleanup();
|
||||
exit(1);
|
||||
case ButtonPress:
|
||||
buttonpress(&ev);
|
||||
buttonpress_x11(&ev);
|
||||
noimg = 0;
|
||||
break;
|
||||
case MotionNotify: // currently does nothing
|
||||
|
@ -34,7 +34,7 @@ void eventloop(void) {
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
keypress(&ev);
|
||||
keypress_x11(&ev);
|
||||
noimg = 1;
|
||||
break;
|
||||
case SelectionNotify: // paste selection
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
static void eventloop(void);
|
||||
static void eventloop_x11(void);
|
||||
|
|
|
@ -1,40 +1,29 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
void setupdisplay(void) {
|
||||
void setupdisplay_x11(void) {
|
||||
int x, y, i;
|
||||
#if USEXINERAMA
|
||||
int j, di;
|
||||
#endif
|
||||
unsigned int du;
|
||||
|
||||
unsigned int minstrlen = 0, curstrlen = 0;
|
||||
int numwidthchecks = 100;
|
||||
|
||||
Window w, dw, *dws;
|
||||
XWindowAttributes wa;
|
||||
|
||||
#if USEXINERAMA
|
||||
XineramaScreenInfo *info;
|
||||
Window pw;
|
||||
int a, n, area = 0;
|
||||
#endif
|
||||
|
||||
prepare_window_size();
|
||||
prepare_window_size_x11();
|
||||
|
||||
// resize client to image height if deemed necessary
|
||||
#if USEIMAGE
|
||||
if (image) resizetoimageheight(imageheight);
|
||||
#endif
|
||||
|
||||
mh = (lines + 1) * bh + 2 * menumarginv; // lines + 1 * bh is the menu height
|
||||
|
||||
// set prompt width based on prompt size
|
||||
promptw = (prompt && *prompt)
|
||||
? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0; // prompt width
|
||||
|
||||
get_width(numwidthchecks, minstrlen, curstrlen);
|
||||
|
||||
// init xinerama screens
|
||||
#if USEXINERAMA
|
||||
XineramaScreenInfo *info;
|
||||
Window pw;
|
||||
int a, n, area = 0;
|
||||
int j, di;
|
||||
|
||||
i = 0;
|
||||
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
|
||||
XGetInputFocus(dpy, &w, &di);
|
||||
|
@ -63,8 +52,8 @@ void setupdisplay(void) {
|
|||
// calculate x/y position
|
||||
if (menuposition == 2) { // centered
|
||||
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width);
|
||||
x = info[i].x_org + ((info[i].width - mw) / 2);
|
||||
y = info[i].y_org + ((info[i].height - mh) / 2);
|
||||
x = info[i].x_org + xpos + ((info[i].width - mw) / 2);
|
||||
y = info[i].y_org - ypos + ((info[i].height - mh) / 2);
|
||||
} else { // top or bottom
|
||||
x = info[i].x_org + xpos;
|
||||
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos);
|
||||
|
@ -81,28 +70,25 @@ void setupdisplay(void) {
|
|||
|
||||
if (menuposition == 2) { // centered
|
||||
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width);
|
||||
x = (wa.width - mw) / 2;
|
||||
y = (wa.height - mh) / 2;
|
||||
x = (wa.width - mw) / 2 + xpos;
|
||||
y = (wa.height - mh) / 2 - ypos;
|
||||
} else { // top or bottom
|
||||
x = 0;
|
||||
y = menuposition ? 0 : wa.width - mh - ypos;
|
||||
mw = wa.width;
|
||||
mw = (menuwidth > 0 ? menuwidth : wa.width);
|
||||
}
|
||||
}
|
||||
|
||||
// might be faster in some instances, most of the time unnecessary
|
||||
if (!accuratewidth) inputw = MIN(inputw, mw/3);
|
||||
|
||||
// create menu window and set properties for it
|
||||
create_window(
|
||||
create_window_x11(
|
||||
x + sp,
|
||||
y + vp - (menuposition == 1 ? 0 : menuposition == 2 ? borderwidth : borderwidth * 2),
|
||||
mw - 2 * sp - borderwidth * 2,
|
||||
mh
|
||||
);
|
||||
|
||||
set_window();
|
||||
set_prop();
|
||||
set_window_x11();
|
||||
set_prop_x11();
|
||||
|
||||
#if USEIMAGE
|
||||
setimageopts();
|
||||
|
@ -139,11 +125,25 @@ void setupdisplay(void) {
|
|||
drawmenu();
|
||||
}
|
||||
|
||||
Display * opendisplay(char *disp) {
|
||||
void prepare_window_size_x11(void) {
|
||||
sp = menupaddingh;
|
||||
vp = (menuposition == 1) ? menupaddingv : - menupaddingv;
|
||||
|
||||
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight);
|
||||
lines = MAX(lines, 0);
|
||||
reallines = lines;
|
||||
|
||||
lrpad = drw->font->h + textpadding;
|
||||
mh = (lines + 1) * bh + 2 * menumarginv; // lines + 1 * bh is the menu height
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Display * opendisplay_x11(char *disp) {
|
||||
return XOpenDisplay(disp);
|
||||
}
|
||||
|
||||
void set_screen(Display *disp) {
|
||||
void set_screen_x11(Display *disp) {
|
||||
screen = DefaultScreen(disp);
|
||||
root = RootWindow(disp, screen);
|
||||
}
|
||||
|
@ -157,11 +157,11 @@ void handle_x11(void) {
|
|||
if (!XSetLocaleModifiers(""))
|
||||
fputs("warning: no locale modifiers support\n", stderr);
|
||||
|
||||
if (!(dpy = opendisplay(NULL)))
|
||||
if (!(dpy = opendisplay_x11(NULL)))
|
||||
die("spmenu: cannot open display"); // failed to open display
|
||||
|
||||
// set screen and root window
|
||||
set_screen(dpy);
|
||||
set_screen_x11(dpy);
|
||||
|
||||
// parent window is the root window (ie. window manager) because we're not embedding
|
||||
if (!embed || !(parentwin = strtol(embed, NULL, 0)))
|
||||
|
@ -172,7 +172,7 @@ void handle_x11(void) {
|
|||
}
|
||||
|
||||
xinitvisual(); // init visual and create drawable after
|
||||
drw = drw_create(dpy, screen, root, wa.width, wa.height, visual, depth, cmap);
|
||||
drw = drw_create_x11(dpy, screen, root, wa.width, wa.height, visual, depth, cmap, protocol);
|
||||
}
|
||||
|
||||
void cleanup_x11(Display *disp) {
|
||||
|
|
|
@ -4,8 +4,9 @@ static Atom clip, utf8, types, dock;
|
|||
static Display *dpy;
|
||||
static Window root, parentwin, win;
|
||||
|
||||
static void setupdisplay(void);
|
||||
static void set_screen(Display *disp);
|
||||
static void setupdisplay_x11(void);
|
||||
static void set_screen_x11(Display *disp);
|
||||
static void handle_x11(void);
|
||||
static void cleanup_x11(Display *disp);
|
||||
static Display * opendisplay(char *disp);
|
||||
static void prepare_window_size_x11(void);
|
||||
static Display * opendisplay_x11(char *disp);
|
||||
|
|
|
@ -14,7 +14,7 @@ void updatenumlockmask(void) {
|
|||
XFreeModifiermap(modmap);
|
||||
}
|
||||
|
||||
void keypress(XEvent *e) {
|
||||
void keypress_x11(XEvent *e) {
|
||||
updatenumlockmask();
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -73,7 +73,7 @@ void keypress(XEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void grabkeyboard(void) {
|
||||
void grabkeyboard_x11(void) {
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
|
||||
int i;
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ typedef struct {
|
|||
#define ShiftGr Mod5Mask
|
||||
|
||||
static void updatenumlockmask(void);
|
||||
static void keypress(XEvent *e);
|
||||
static void grabkeyboard(void);
|
||||
static void keypress_x11(XEvent *e);
|
||||
static void grabkeyboard_x11(void);
|
||||
static void getcapsstate(void);
|
||||
|
||||
static Key ckeys[256];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
void buttonpress(XEvent *e) {
|
||||
void buttonpress_x11(XEvent *e) {
|
||||
struct item *item;
|
||||
XButtonPressedEvent *ev = &e->xbutton;
|
||||
int x = 0, y = 0, h = bh, w, item_num = 0;
|
||||
|
@ -68,7 +68,7 @@ void buttonpress(XEvent *e) {
|
|||
if (ev->y >= y && ev->y <= (y + h) && ev->x >= x && ev->x <= (x + w / columns)) {
|
||||
for (i = 0; i < LENGTH(buttons); i++) {
|
||||
if (ignoreglobalmouse) break;
|
||||
if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
|
||||
if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (buttons[i].click == ClickItem) {
|
||||
|
@ -77,7 +77,7 @@ void buttonpress(XEvent *e) {
|
|||
}
|
||||
for (i = 0; i < LENGTH(cbuttons); i++) {
|
||||
if (ignoreconfmouse) break;
|
||||
if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button && CLEANMASK(cbuttons[i].mask) == CLEANMASK(ev->state)) {
|
||||
if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (cbuttons[i].click == ClickItem) {
|
||||
|
@ -103,7 +103,7 @@ void buttonpress(XEvent *e) {
|
|||
if (ev->x >= x && ev->x <= x + w) {
|
||||
for (i = 0; i < LENGTH(buttons); i++) {
|
||||
if (ignoreglobalmouse) break;
|
||||
if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) {
|
||||
if (buttons[i].click == ClickSelItem && buttons[i].button == ev->button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (buttons[i].click == ClickItem) {
|
||||
|
@ -112,7 +112,7 @@ void buttonpress(XEvent *e) {
|
|||
}
|
||||
for (i = 0; i < LENGTH(cbuttons); i++) {
|
||||
if (ignoreconfmouse) break;
|
||||
if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button && CLEANMASK(cbuttons[i].mask) == CLEANMASK(ev->state)) {
|
||||
if (cbuttons[i].click == ClickSelItem && cbuttons[i].button == ev->button) {
|
||||
puts(item->text);
|
||||
exit(0);
|
||||
} else if (cbuttons[i].click == ClickItem) {
|
||||
|
@ -133,16 +133,14 @@ void buttonpress(XEvent *e) {
|
|||
// go through mouse button array and run function
|
||||
for (i = 0; i < LENGTH(buttons); i++) {
|
||||
if (ignoreglobalmouse) break;
|
||||
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
|
||||
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
|
||||
if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button)
|
||||
buttons[i].func(&buttons[i].arg);
|
||||
}
|
||||
|
||||
// go through mouse config array and run function
|
||||
for (i = 0; i < LENGTH(cbuttons); i++) {
|
||||
if (ignoreconfmouse) break;
|
||||
if (click == cbuttons[i].click && cbuttons[i].func && cbuttons[i].button == ev->button
|
||||
&& CLEANMASK(cbuttons[i].mask) == CLEANMASK(ev->state))
|
||||
if (click == cbuttons[i].click && cbuttons[i].func && cbuttons[i].button == ev->button)
|
||||
cbuttons[i].func(&cbuttons[i].arg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,10 @@ enum {
|
|||
|
||||
typedef struct {
|
||||
unsigned int click;
|
||||
unsigned int mask;
|
||||
unsigned int button;
|
||||
void (*func)(Arg *arg);
|
||||
Arg arg;
|
||||
} Mouse;
|
||||
|
||||
static Mouse cbuttons[256];
|
||||
static void buttonpress(XEvent *e);
|
||||
static void buttonpress_x11(XEvent *e);
|
||||
|
|
|
@ -120,7 +120,6 @@ ResourcePref resources[] = {
|
|||
{ "selitempadding", INTEGER, &selitempadding },
|
||||
{ "priitempadding", INTEGER, &priitempadding },
|
||||
{ "indentitems", INTEGER, &indentitems },
|
||||
{ "accuratewidth", INTEGER, &accuratewidth },
|
||||
{ "alpha", INTEGER, &alpha },
|
||||
{ "type", INTEGER, &type },
|
||||
{ "passwd", INTEGER, &passwd },
|
||||
|
|
17
meson.build
17
meson.build
|
@ -1,7 +1,7 @@
|
|||
project(
|
||||
'spmenu',
|
||||
'c',
|
||||
version : '"1.2.1"',
|
||||
version : '"2.0"',
|
||||
default_options : ['warning_level=3']
|
||||
)
|
||||
|
||||
|
@ -39,6 +39,21 @@ build_args = [
|
|||
'-Wno-sign-compare',
|
||||
]
|
||||
|
||||
if get_option('wayland')
|
||||
project_dependencies += [ dependency('wayland-client') ]
|
||||
project_dependencies += [ dependency('wayland-scanner') ]
|
||||
project_dependencies += [ dependency('wayland-protocols') ]
|
||||
project_dependencies += [ dependency('xkbcommon') ]
|
||||
project_source_files += [ 'libs/wl/wlr-layer-shell-unstable-v1-client-protocol.h' ]
|
||||
project_source_files += [ 'libs/wl/wlr-layer-shell-unstable-v1-protocol.c' ]
|
||||
project_source_files += [ 'libs/wl/xdg-output-unstable-v1-client-protocol.h' ]
|
||||
project_source_files += [ 'libs/wl/xdg-output-unstable-v1-protocol.c' ]
|
||||
project_source_files += [ 'libs/wl/xdg-shell-client-protocol.h' ]
|
||||
project_source_files += [ 'libs/wl/xdg-shell-protocol.c' ]
|
||||
build_args += [ '-DWAYLAND' ]
|
||||
run_command('scripts/make/generate-headers.sh', check : false)
|
||||
endif
|
||||
|
||||
if get_option('imlib2') and get_option('openssl')
|
||||
project_dependencies += [ dependency('imlib2') ]
|
||||
project_dependencies += [ dependency('openssl') ]
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
option(
|
||||
'wayland',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description : 'Enable Wayland support'
|
||||
)
|
||||
|
||||
option(
|
||||
'imlib2',
|
||||
type : 'boolean',
|
||||
|
|
22
mouse.h
22
mouse.h
|
@ -5,10 +5,22 @@
|
|||
* See LICENSE file for copyright and license details.
|
||||
*/
|
||||
|
||||
/* Only applies to X11 */
|
||||
static Mouse buttons[] = {
|
||||
{ ClickInput, 0, Button1, clear, {0} },
|
||||
{ ClickPrompt, 0, Button1, clear, {0} },
|
||||
{ ClickMode, 0, Button1, switchmode, {0} },
|
||||
{ ClickNumber, 0, Button1, viewhist, {0} },
|
||||
{ ClickSelItem, 0, Button1, NULL, {0} },
|
||||
{ ClickInput, Button1, clear, {0} },
|
||||
{ ClickPrompt, Button1, clear, {0} },
|
||||
{ ClickMode, Button1, switchmode, {0} },
|
||||
{ ClickNumber, Button1, viewhist, {0} },
|
||||
{ ClickSelItem, Button1, NULL, {0} },
|
||||
};
|
||||
|
||||
/* Only applies to Wayland */
|
||||
#if USEWAYLAND
|
||||
static Mouse wl_buttons[] = {
|
||||
{ ClickInput, WL_Left, clear, {0} },
|
||||
{ ClickPrompt, WL_Left, clear, {0} },
|
||||
{ ClickMode, WL_Left, switchmode, {0} },
|
||||
{ ClickNumber, WL_Left, viewhist, {0} },
|
||||
{ ClickSelItem, WL_Left, NULL, {0} },
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
|
||||
/* spmenu options */
|
||||
static char *class = "spmenu"; /* Class for spmenu */
|
||||
static int protocol = 1; /* Protocol to try first (0: X11, 1: Wayland) */
|
||||
static int fast = 0; /* Grab keyboard first */
|
||||
static int xresources = 1; /* Enable .Xresources support */
|
||||
static int globalcolors = 1; /* Recognize global colors (such as colors generated by Pywal) */
|
||||
static int loadconfig = 1; /* Load configuration (~/.config/spmenu/spmenu.conf) on runtime */
|
||||
static int loadtheme = 1; /* Load theme (~/.theme.conf or ~/.config/spmenu/theme.conf) on runtime */
|
||||
static int loadtheme = 1; /* Load theme (~/.config/spmenu/theme.conf) on runtime */
|
||||
static int loadbinds = 1; /* Load keybind file (~/.config/spmenu/binds.conf) on runtime */
|
||||
static int mon = -1; /* Monitor to run spmenu on */
|
||||
|
||||
|
@ -19,7 +20,7 @@ static int alpha = 1; /* Enable alpha */
|
|||
static int menuposition = 2; /* Position of the menu (0: Bottom, 1: Top, 2: Center */
|
||||
static int menupaddingv = 0; /* Vertical padding inside the menu (in pixels) */
|
||||
static int menupaddingh = 0; /* Horizontal padding inside the menu (in pixels) */
|
||||
static int menuwidth = 0; /* spmenu width when setting X/Y position */
|
||||
static int menuwidth = 0; /* spmenu width */
|
||||
static int menumarginv = 0; /* Vertical padding around the menu */
|
||||
static int menumarginh = 0; /* Horizontal padding around the menu */
|
||||
static int minwidth = 1000; /* Minimum width when centered */
|
||||
|
@ -80,7 +81,6 @@ static int sortmatches = 1; /* Sort matches (0/1) */
|
|||
static int casesensitive = 0; /* Case-sensitive by default? (0/1) */
|
||||
static int mark = 1; /* Enable marking items (multi selection) (0/1) */
|
||||
static int preselected = 0; /* Which line should spmenu preselect? */
|
||||
static int accuratewidth = 0; /* Enable accurate width. May have a performance hit if you are matching a lot of items at once */
|
||||
static int fuzzy = 1; /* Whether or not to enable fuzzy matching by default */
|
||||
static char *listfile = NULL; /* File to read entries from instead of stdin. NULL means read from stdin instead. */
|
||||
|
||||
|
|
285
protocols/wlr-layer-shell-unstable-v1.xml
Normal file
285
protocols/wlr-layer-shell-unstable-v1.xml
Normal file
|
@ -0,0 +1,285 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_layer_shell_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2017 Drew DeVault
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwlr_layer_shell_v1" version="1">
|
||||
<description summary="create surfaces that are layers of the desktop">
|
||||
Clients can use this interface to assign the surface_layer role to
|
||||
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||
rendered with a defined z-depth respective to each other. They may also be
|
||||
anchored to the edges and corners of a screen and specify input handling
|
||||
semantics. This interface should be suitable for the implementation of
|
||||
many desktop shell components, and a broad number of other applications
|
||||
that interact with the desktop.
|
||||
</description>
|
||||
|
||||
<request name="get_layer_surface">
|
||||
<description summary="create a layer_surface from a surface">
|
||||
Create a layer surface for an existing surface. This assigns the role of
|
||||
layer_surface, or raises a protocol error if another role is already
|
||||
assigned.
|
||||
|
||||
Creating a layer surface from a wl_surface which has a buffer attached
|
||||
or committed is a client error, and any attempts by a client to attach
|
||||
or manipulate a buffer prior to the first layer_surface.configure call
|
||||
must also be treated as errors.
|
||||
|
||||
You may pass NULL for output to allow the compositor to decide which
|
||||
output to use. Generally this will be the one that the user most
|
||||
recently interacted with.
|
||||
|
||||
Clients can specify a namespace that defines the purpose of the layer
|
||||
surface.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
|
||||
<arg name="namespace" type="string" summary="namespace for the layer surface"/>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="role" value="0" summary="wl_surface has another role"/>
|
||||
<entry name="invalid_layer" value="1" summary="layer value is invalid"/>
|
||||
<entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
|
||||
</enum>
|
||||
|
||||
<enum name="layer">
|
||||
<description summary="available layers for surfaces">
|
||||
These values indicate which layers a surface can be rendered in. They
|
||||
are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||
will typically be rendered between the bottom and top layers.
|
||||
Fullscreen shell surfaces are typically rendered at the top layer.
|
||||
Multiple surfaces can share a single layer, and ordering within a
|
||||
single layer is undefined.
|
||||
</description>
|
||||
|
||||
<entry name="background" value="0"/>
|
||||
<entry name="bottom" value="1"/>
|
||||
<entry name="top" value="2"/>
|
||||
<entry name="overlay" value="3"/>
|
||||
</enum>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_layer_surface_v1" version="1">
|
||||
<description summary="layer metadata interface">
|
||||
An interface that may be implemented by a wl_surface, for surfaces that
|
||||
are designed to be rendered as a layer of a stacked desktop-like
|
||||
environment.
|
||||
|
||||
Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||
is double-buffered, and will be applied at the time wl_surface.commit of
|
||||
the corresponding wl_surface is called.
|
||||
</description>
|
||||
|
||||
<request name="set_size">
|
||||
<description summary="sets the size of the surface">
|
||||
Sets the size of the surface in surface-local coordinates. The
|
||||
compositor will display the surface centered with respect to its
|
||||
anchors.
|
||||
|
||||
If you pass 0 for either value, the compositor will assign it and
|
||||
inform you of the assignment in the configure event. You must set your
|
||||
anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||
protocol error. Both values are 0 by default.
|
||||
|
||||
Size is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="set_anchor">
|
||||
<description summary="configures the anchor point of the surface">
|
||||
Requests that the compositor anchor the surface to the specified edges
|
||||
and corners. If two orthoginal edges are specified (e.g. 'top' and
|
||||
'left'), then the anchor point will be the intersection of the edges
|
||||
(e.g. the top left corner of the output); otherwise the anchor point
|
||||
will be centered on that edge, or in the center if none is specified.
|
||||
|
||||
Anchor is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="anchor" type="uint" enum="anchor"/>
|
||||
</request>
|
||||
|
||||
<request name="set_exclusive_zone">
|
||||
<description summary="configures the exclusive geometry of this surface">
|
||||
Requests that the compositor avoids occluding an area of the surface
|
||||
with other surfaces. The compositor's use of this information is
|
||||
implementation-dependent - do not assume that this region will not
|
||||
actually be occluded.
|
||||
|
||||
A positive value is only meaningful if the surface is anchored to an
|
||||
edge, rather than a corner. The zone is the number of surface-local
|
||||
coordinates from the edge that are considered exclusive.
|
||||
|
||||
Surfaces that do not wish to have an exclusive zone may instead specify
|
||||
how they should interact with surfaces that do. If set to zero, the
|
||||
surface indicates that it would like to be moved to avoid occluding
|
||||
surfaces with a positive excluzive zone. If set to -1, the surface
|
||||
indicates that it would not like to be moved to accommodate for other
|
||||
surfaces, and the compositor should extend it all the way to the edges
|
||||
it is anchored to.
|
||||
|
||||
For example, a panel might set its exclusive zone to 10, so that
|
||||
maximized shell surfaces are not shown on top of it. A notification
|
||||
might set its exclusive zone to 0, so that it is moved to avoid
|
||||
occluding the panel, but shell surfaces are shown underneath it. A
|
||||
wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||
they stretch below or over the panel.
|
||||
|
||||
The default value is 0.
|
||||
|
||||
Exclusive zone is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="zone" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_margin">
|
||||
<description summary="sets a margin from the anchor point">
|
||||
Requests that the surface be placed some distance away from the anchor
|
||||
point on the output, in surface-local coordinates. Setting this value
|
||||
for edges you are not anchored to has no effect.
|
||||
|
||||
The exclusive zone includes the margin.
|
||||
|
||||
Margin is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="top" type="int"/>
|
||||
<arg name="right" type="int"/>
|
||||
<arg name="bottom" type="int"/>
|
||||
<arg name="left" type="int"/>
|
||||
</request>
|
||||
|
||||
<request name="set_keyboard_interactivity">
|
||||
<description summary="requests keyboard events">
|
||||
Set to 1 to request that the seat send keyboard events to this layer
|
||||
surface. For layers below the shell surface layer, the seat will use
|
||||
normal focus semantics. For layers above the shell surface layers, the
|
||||
seat will always give exclusive keyboard focus to the top-most layer
|
||||
which has keyboard interactivity set to true.
|
||||
|
||||
Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||
you do not want to receive them, set the input region on your surface
|
||||
to an empty region.
|
||||
|
||||
Events is double-buffered, see wl_surface.commit.
|
||||
</description>
|
||||
<arg name="keyboard_interactivity" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="get_popup">
|
||||
<description summary="assign this layer_surface as an xdg_popup parent">
|
||||
This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||
should have been created via xdg_surface::get_popup with the parent set
|
||||
to NULL, and this request must be invoked before committing the popup's
|
||||
initial state.
|
||||
|
||||
See the documentation of xdg_popup for more details about what an
|
||||
xdg_popup is and how it is used.
|
||||
</description>
|
||||
<arg name="popup" type="object" interface="xdg_popup"/>
|
||||
</request>
|
||||
|
||||
<request name="ack_configure">
|
||||
<description summary="ack a configure event">
|
||||
When a configure event is received, if a client commits the
|
||||
surface in response to the configure event, then the client
|
||||
must make an ack_configure request sometime before the commit
|
||||
request, passing along the serial of the configure event.
|
||||
|
||||
If the client receives multiple configure events before it
|
||||
can respond to one, it only has to ack the last configure event.
|
||||
|
||||
A client is not required to commit immediately after sending
|
||||
an ack_configure request - it may even ack_configure several times
|
||||
before its next surface commit.
|
||||
|
||||
A client may send multiple ack_configure requests before committing, but
|
||||
only the last request sent before a commit indicates which configure
|
||||
event the client really is responding to.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||
</request>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the layer_surface">
|
||||
This request destroys the layer surface.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="configure">
|
||||
<description summary="suggest a surface change">
|
||||
The configure event asks the client to resize its surface.
|
||||
|
||||
Clients should arrange their surface for the new states, and then send
|
||||
an ack_configure request with the serial sent in this configure event at
|
||||
some point before committing the new surface.
|
||||
|
||||
The client is free to dismiss all but the last configure event it
|
||||
received.
|
||||
|
||||
The width and height arguments specify the size of the window in
|
||||
surface-local coordinates.
|
||||
|
||||
The size is a hint, in the sense that the client is free to ignore it if
|
||||
it doesn't resize, pick a smaller size (to satisfy aspect ratio or
|
||||
resize in steps of NxM pixels). If the client picks a smaller size and
|
||||
is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
|
||||
surface will be centered on this axis.
|
||||
|
||||
If the width or height arguments are zero, it means the client should
|
||||
decide its own window dimension.
|
||||
</description>
|
||||
<arg name="serial" type="uint"/>
|
||||
<arg name="width" type="uint"/>
|
||||
<arg name="height" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="closed">
|
||||
<description summary="surface should be closed">
|
||||
The closed event is sent by the compositor when the surface will no
|
||||
longer be shown. The output may have been destroyed or the user may
|
||||
have asked for it to be removed. Further changes to the surface will be
|
||||
ignored. The client should destroy the resource after receiving this
|
||||
event, and create a new surface if they so choose.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
|
||||
<entry name="invalid_size" value="1" summary="size is invalid"/>
|
||||
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
|
||||
</enum>
|
||||
|
||||
<enum name="anchor" bitfield="true">
|
||||
<entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
|
||||
<entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
|
||||
<entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
|
||||
<entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
|
||||
</enum>
|
||||
</interface>
|
||||
</protocol>
|
222
protocols/xdg-output-unstable-v1.xml
Normal file
222
protocols/xdg-output-unstable-v1.xml
Normal file
|
@ -0,0 +1,222 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_output_unstable_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2017 Red Hat Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Protocol to describe output regions">
|
||||
This protocol aims at describing outputs in a way which is more in line
|
||||
with the concept of an output on desktop oriented systems.
|
||||
|
||||
Some information are more specific to the concept of an output for
|
||||
a desktop oriented system and may not make sense in other applications,
|
||||
such as IVI systems for example.
|
||||
|
||||
Typically, the global compositor space on a desktop system is made of
|
||||
a contiguous or overlapping set of rectangular regions.
|
||||
|
||||
The logical_position and logical_size events defined in this protocol
|
||||
might provide information identical to their counterparts already
|
||||
available from wl_output, in which case the information provided by this
|
||||
protocol should be preferred to their equivalent in wl_output. The goal is
|
||||
to move the desktop specific concepts (such as output location within the
|
||||
global compositor space, etc.) out of the core wl_output protocol.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible
|
||||
changes may be added together with the corresponding interface
|
||||
version bump.
|
||||
Backward incompatible changes are done by bumping the version
|
||||
number in the protocol and interface names and resetting the
|
||||
interface version. Once the protocol is to be declared stable,
|
||||
the 'z' prefix and the version number in the protocol and
|
||||
interface names are removed and the interface version number is
|
||||
reset.
|
||||
</description>
|
||||
|
||||
<interface name="zxdg_output_manager_v1" version="3">
|
||||
<description summary="manage xdg_output objects">
|
||||
A global factory interface for xdg_output objects.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_output_manager object">
|
||||
Using this request a client can tell the server that it is not
|
||||
going to use the xdg_output_manager object anymore.
|
||||
|
||||
Any objects already created through this instance are not affected.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_xdg_output">
|
||||
<description summary="create an xdg output from a wl_output">
|
||||
This creates a new xdg_output object for the given wl_output.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zxdg_output_v1"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zxdg_output_v1" version="3">
|
||||
<description summary="compositor logical output region">
|
||||
An xdg_output describes part of the compositor geometry.
|
||||
|
||||
This typically corresponds to a monitor that displays part of the
|
||||
compositor space.
|
||||
|
||||
For objects version 3 onwards, after all xdg_output properties have been
|
||||
sent (when the object is created and when properties are updated), a
|
||||
wl_output.done event is sent. This allows changes to the output
|
||||
properties to be seen as atomic, even if they happen via multiple events.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_output object">
|
||||
Using this request a client can tell the server that it is not
|
||||
going to use the xdg_output object anymore.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="logical_position">
|
||||
<description summary="position of the output within the global compositor space">
|
||||
The position event describes the location of the wl_output within
|
||||
the global compositor space.
|
||||
|
||||
The logical_position event is sent after creating an xdg_output
|
||||
(see xdg_output_manager.get_xdg_output) and whenever the location
|
||||
of the output changes within the global compositor space.
|
||||
</description>
|
||||
<arg name="x" type="int"
|
||||
summary="x position within the global compositor space"/>
|
||||
<arg name="y" type="int"
|
||||
summary="y position within the global compositor space"/>
|
||||
</event>
|
||||
|
||||
<event name="logical_size">
|
||||
<description summary="size of the output in the global compositor space">
|
||||
The logical_size event describes the size of the output in the
|
||||
global compositor space.
|
||||
|
||||
Most regular Wayland clients should not pay attention to the
|
||||
logical size and would rather rely on xdg_shell interfaces.
|
||||
|
||||
Some clients such as Xwayland, however, need this to configure
|
||||
their surfaces in the global compositor space as the compositor
|
||||
may apply a different scale from what is advertised by the output
|
||||
scaling property (to achieve fractional scaling, for example).
|
||||
|
||||
For example, for a wl_output mode 3840×2160 and a scale factor 2:
|
||||
|
||||
- A compositor not scaling the monitor viewport in its compositing space
|
||||
will advertise a logical size of 3840×2160,
|
||||
|
||||
- A compositor scaling the monitor viewport with scale factor 2 will
|
||||
advertise a logical size of 1920×1080,
|
||||
|
||||
- A compositor scaling the monitor viewport using a fractional scale of
|
||||
1.5 will advertise a logical size of 2560×1440.
|
||||
|
||||
For example, for a wl_output mode 1920×1080 and a 90 degree rotation,
|
||||
the compositor will advertise a logical size of 1080x1920.
|
||||
|
||||
The logical_size event is sent after creating an xdg_output
|
||||
(see xdg_output_manager.get_xdg_output) and whenever the logical
|
||||
size of the output changes, either as a result of a change in the
|
||||
applied scale or because of a change in the corresponding output
|
||||
mode(see wl_output.mode) or transform (see wl_output.transform).
|
||||
</description>
|
||||
<arg name="width" type="int"
|
||||
summary="width in global compositor space"/>
|
||||
<arg name="height" type="int"
|
||||
summary="height in global compositor space"/>
|
||||
</event>
|
||||
|
||||
<event name="done">
|
||||
<description summary="all information about the output have been sent">
|
||||
This event is sent after all other properties of an xdg_output
|
||||
have been sent.
|
||||
|
||||
This allows changes to the xdg_output properties to be seen as
|
||||
atomic, even if they happen via multiple events.
|
||||
|
||||
For objects version 3 onwards, this event is deprecated. Compositors
|
||||
are not required to send it anymore and must send wl_output.done
|
||||
instead.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
|
||||
<event name="name" since="2">
|
||||
<description summary="name of this output">
|
||||
Many compositors will assign names to their outputs, show them to the
|
||||
user, allow them to be configured by name, etc. The client may wish to
|
||||
know this name as well to offer the user similar behaviors.
|
||||
|
||||
The naming convention is compositor defined, but limited to
|
||||
alphanumeric characters and dashes (-). Each name is unique among all
|
||||
wl_output globals, but if a wl_output global is destroyed the same name
|
||||
may be reused later. The names will also remain consistent across
|
||||
sessions with the same hardware and software configuration.
|
||||
|
||||
Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
|
||||
not assume that the name is a reflection of an underlying DRM
|
||||
connector, X11 connection, etc.
|
||||
|
||||
The name event is sent after creating an xdg_output (see
|
||||
xdg_output_manager.get_xdg_output). This event is only sent once per
|
||||
xdg_output, and the name does not change over the lifetime of the
|
||||
wl_output global.
|
||||
|
||||
This event is deprecated, instead clients should use wl_output.name.
|
||||
Compositors must still support this event.
|
||||
</description>
|
||||
<arg name="name" type="string" summary="output name"/>
|
||||
</event>
|
||||
|
||||
<event name="description" since="2">
|
||||
<description summary="human-readable description of this output">
|
||||
Many compositors can produce human-readable descriptions of their
|
||||
outputs. The client may wish to know this description as well, to
|
||||
communicate the user for various purposes.
|
||||
|
||||
The description is a UTF-8 string with no convention defined for its
|
||||
contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
|
||||
output via :1'.
|
||||
|
||||
The description event is sent after creating an xdg_output (see
|
||||
xdg_output_manager.get_xdg_output) and whenever the description
|
||||
changes. The description is optional, and may not be sent at all.
|
||||
|
||||
For objects of version 2 and lower, this event is only sent once per
|
||||
xdg_output, and the description does not change over the lifetime of
|
||||
the wl_output global.
|
||||
|
||||
This event is deprecated, instead clients should use
|
||||
wl_output.description. Compositors must still support this event.
|
||||
</description>
|
||||
<arg name="description" type="string" summary="output description"/>
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
1361
protocols/xdg-shell.xml
Normal file
1361
protocols/xdg-shell.xml
Normal file
File diff suppressed because it is too large
Load diff
|
@ -25,6 +25,7 @@ loadconf() {
|
|||
build() {
|
||||
[ ! -f "meson.build" ] && printf "meson.build does not exist.\n" && exit 1
|
||||
[ "$gen_manual" != "false" ] && [ -x "$(command -v pandoc)" ] && scripts/make/generate-docs.sh
|
||||
[ -z "$wayland" ] && wayland=true
|
||||
|
||||
cp -f meson.build meson.build.orig
|
||||
|
||||
|
@ -42,6 +43,7 @@ build() {
|
|||
-Dimlib2="$imlib2" \
|
||||
-Dopenssl="$openssl" \
|
||||
-Dlibconfig="$libconfig" \
|
||||
-Dwayland="$wayland" \
|
||||
--prefix "$prefix" \
|
||||
build
|
||||
else
|
||||
|
@ -52,6 +54,7 @@ build() {
|
|||
-Dimlib2="$imlib2" \
|
||||
-Dopenssl="$openssl" \
|
||||
-Dlibconfig="$libconfig" \
|
||||
-Dwayland="$wayland" \
|
||||
--prefix "$prefix" \
|
||||
build
|
||||
fi
|
||||
|
@ -69,6 +72,7 @@ install() {
|
|||
[ "$reconfigure" = "true" ] && rm -rf build/
|
||||
}
|
||||
|
||||
[ "$(id -u)" != "0" ] && [ "$install" != "false" ] && printf "Run as root.\n" && exit 1
|
||||
check
|
||||
loadconf
|
||||
build
|
||||
|
|
31
scripts/make/generate-headers.sh
Executable file
31
scripts/make/generate-headers.sh
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/sh
|
||||
[ ! -x "$(command -v wayland-scanner)" ] && exit 1
|
||||
wayland-scanner \
|
||||
client-header \
|
||||
protocols/wlr-layer-shell-unstable-v1.xml \
|
||||
libs/wl/wlr-layer-shell-unstable-v1-client-protocol.h
|
||||
|
||||
wayland-scanner \
|
||||
client-header \
|
||||
protocols/xdg-shell.xml \
|
||||
libs/wl/xdg-shell-client-protocol.h
|
||||
|
||||
wayland-scanner \
|
||||
client-header \
|
||||
protocols/xdg-output-unstable-v1.xml \
|
||||
libs/wl/xdg-output-unstable-v1-client-protocol.h
|
||||
|
||||
wayland-scanner \
|
||||
public-code \
|
||||
protocols/wlr-layer-shell-unstable-v1.xml \
|
||||
libs/wl/wlr-layer-shell-unstable-v1-protocol.c
|
||||
|
||||
wayland-scanner \
|
||||
public-code \
|
||||
protocols/xdg-shell.xml \
|
||||
libs/wl/xdg-shell-protocol.c
|
||||
|
||||
wayland-scanner \
|
||||
public-code \
|
||||
protocols/xdg-output-unstable-v1.xml \
|
||||
libs/wl/xdg-output-unstable-v1-protocol.c
|
|
@ -4,7 +4,7 @@ version="$(grep "version : '" meson.build | awk '{ print $3 }' | sed "s/'\"//g;
|
|||
|
||||
rm -f spmenu spmenu-${version}.tar.gz spmenu-${version}.PKGBUILD *.o *zst*
|
||||
mkdir -p spmenu-${version}
|
||||
cp -rf LICENSE meson.build meson.options *.h *.c scripts/ docs/ libs/ PKGBUILD spmenu-${version}
|
||||
cp -rf LICENSE meson.build meson.options *.h *.c scripts/ docs/ libs/ protocols/ PKGBUILD spmenu-${version}
|
||||
[ -f Makefile ] && cp Makefile spmenu-${version} || :
|
||||
[ -f host.mk ] && cp host.mk spmenu-${version} || :
|
||||
[ -f toggle.mk ] && cp toggle.mk spmenu-${version} || :
|
||||
|
|
|
@ -71,7 +71,7 @@ l[24]=y
|
|||
l[25]=z
|
||||
|
||||
main() {
|
||||
printf "${v2}s${v3}p${v4}m${v5}e${v6}n${v7}u${v8} $(spmenu -v | sed 's/spmenu-//g')\n\
|
||||
printf "${v2}s${v3}p${v4}m${v5}e${v6}n${v7}u${v8} $(${RUNLAUNCHER:-spmenu} -v | sed 's/spmenu-//g')\n\
|
||||
\n<big><u>Formatting</u></big>\n\n\
|
||||
abcdefghijklmnopqrstuvwxyz\n\
|
||||
<b>abcdefghijklmnopqrstuvwxyz</b> - b\n\
|
||||
|
@ -153,4 +153,4 @@ printf "\n\n<big><u>The End</u></big>\n"
|
|||
printf "\nIf spmenu displayed 256 colors as well as various forms of formatted text, everything works fine.\nOtherwise, please file a bug report.\n"
|
||||
}
|
||||
|
||||
main "$@" | spmenu --no-alpha --lines 40 "$@" --columns 1 --prompt "<big>spmenu <i>test</i> <small>script</small></big>"
|
||||
main "$@" | ${RUNLAUNCHER:-spmenu} --no-alpha --lines 40 "$@" --columns 1 --prompt "<big>spmenu <i>test</i> <small>script</small></big>"
|
||||
|
|
60
spmenu.1
60
spmenu.1
|
@ -15,13 +15,13 @@
|
|||
. ftr VB CB
|
||||
. ftr VBI CBI
|
||||
.\}
|
||||
.TH "spmenu" "1" "" "1.2.1" "fancy dynamic menu"
|
||||
.TH "spmenu" "1" "" "2.0" "fancy dynamic menu"
|
||||
.hy
|
||||
.SH spmenu
|
||||
.PP
|
||||
spmenu is an X11 menu application which takes standard input, parses it,
|
||||
and lets the user choose an option and sends the selected option to
|
||||
standard output.
|
||||
spmenu is an X11 and Wayland menu application which takes standard
|
||||
input, parses it, lets the user choose an option and sends the selected
|
||||
option to standard output.
|
||||
.PP
|
||||
In addition to this, it also serves as a run launcher through the
|
||||
included shell script \f[V]spmenu_run\f[R], which handles both $PATH
|
||||
|
@ -32,6 +32,8 @@ launcher.
|
|||
While spmenu is based on dmenu, and is also fully compatible with dmenu,
|
||||
spmenu introduces many new features which can be useful in shell
|
||||
scripting.
|
||||
.PP
|
||||
It also serves as a dmenu replacement for Wayland users.
|
||||
.SS Usage
|
||||
.PP
|
||||
On runtime, spmenu reads from standard input (stdin).
|
||||
|
@ -76,12 +78,6 @@ Set max image cache size to size
|
|||
\f[V]-cd, --cache-dir dir\f[R]
|
||||
Set cache directory to dir
|
||||
.TP
|
||||
\f[V]-rw, --relative-width\f[R]
|
||||
Enable relative input width
|
||||
.TP
|
||||
\f[V]-nrw, --no-relative-width\f[R]
|
||||
Disable relative input width
|
||||
.TP
|
||||
\f[V]-ix, --print-index\f[R]
|
||||
Print index instead of actual text
|
||||
.TP
|
||||
|
@ -388,6 +384,12 @@ Load theme (\[ti]/.config/spmenu/theme.conf) on runtime
|
|||
\f[V]-nltm, --no-load-theme\f[R]
|
||||
Don\[cq]t load theme (\[ti]/.config/spmenu/theme.conf) on runtime
|
||||
.TP
|
||||
\f[V]-x11, --x11\f[R]
|
||||
Run spmenu in X11 mode
|
||||
.TP
|
||||
\f[V]-wl, --wayland\f[R]
|
||||
Run spmenu in Wayland mode
|
||||
.TP
|
||||
\f[V]-v, --version\f[R]
|
||||
Print spmenu version to stdout
|
||||
.TP
|
||||
|
@ -1448,6 +1450,8 @@ T}
|
|||
.TE
|
||||
.SS .Xresources
|
||||
.PP
|
||||
\f[B]NOTE: Only applies for X11 users\f[R]
|
||||
.PP
|
||||
spmenu also has .Xresources (xrdb) support built in.
|
||||
It reads the xrdb (.Xresources database) on runtime.
|
||||
You may disable it by passing -nxrdb, or enable it by padding -xrdb.
|
||||
|
@ -1535,6 +1539,42 @@ Print the spmenu version
|
|||
.TP
|
||||
\f[V]spmenu:license\f[R]
|
||||
Print the spmenu license
|
||||
.SS Wayland support
|
||||
.PP
|
||||
Note that Wayland support is still experimental, and some features do
|
||||
not currently work under Wayland.
|
||||
Some will never work under Wayland due to limitations.
|
||||
These are:
|
||||
.IP \[bu] 2
|
||||
Image support
|
||||
.RS 2
|
||||
.IP \[bu] 2
|
||||
Images simply will not be drawn on Wayland.
|
||||
.IP \[bu] 2
|
||||
Will eventually be solved by replacing imlib2 with cairo.
|
||||
.RE
|
||||
.IP \[bu] 2
|
||||
\f[V]--x-position\f[R] and \f[V]--y-position\f[R] arguments
|
||||
.RS 2
|
||||
.IP \[bu] 2
|
||||
These arguments do not work under Wayland, because the layer_shell
|
||||
protocol doesn\[cq]t allow clients to be placed on a specific position.
|
||||
.RE
|
||||
.IP \[bu] 2
|
||||
Embedding \f[V]-w\f[R] and window manager managed \f[V]-wm\f[R]
|
||||
.RS 2
|
||||
.IP \[bu] 2
|
||||
These arguments do not make much sense on Wayland, and embedding is not
|
||||
possible due to the original implementation using XEmbed.
|
||||
If the embed argument is passed it will simply be ignored and the window
|
||||
will be layered as normal.
|
||||
.RE
|
||||
.IP \[bu] 2
|
||||
\f[V]--monitor\f[R] argument
|
||||
.IP \[bu] 2
|
||||
Window borders
|
||||
.IP \[bu] 2
|
||||
Pasting
|
||||
.SS License
|
||||
.PP
|
||||
spmenu is licensed under the MIT license because that\[cq]s the original
|
||||
|
|
112
spmenu.c
112
spmenu.c
|
@ -21,6 +21,8 @@
|
|||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
// set version
|
||||
#ifndef VERSION
|
||||
|
@ -69,6 +71,13 @@
|
|||
#define USEXRESOURCES 1
|
||||
#endif
|
||||
|
||||
// check if we should enable Wayland support
|
||||
#ifndef WAYLAND
|
||||
#define USEWAYLAND 0
|
||||
#else
|
||||
#define USEWAYLAND 1
|
||||
#endif
|
||||
|
||||
// include fribidi used for right to left language support
|
||||
#if USERTL
|
||||
#include <fribidi.h>
|
||||
|
@ -98,6 +107,7 @@ static int allowkeys; // whether or not to interpret a keypress as an insertion
|
|||
#include "libs/schemes.h"
|
||||
#include "libs/arg.h"
|
||||
#include "libs/x11/inc.h" // include x11
|
||||
#include "libs/wl/inc.h" // include wayland
|
||||
#include "libs/sort.h"
|
||||
#include "libs/history.h"
|
||||
|
||||
|
@ -185,8 +195,6 @@ static int depth;
|
|||
static Visual *visual;
|
||||
static Colormap cmap;
|
||||
static Drw *drw;
|
||||
static Clr **scheme;
|
||||
static Clr textclrs[256];
|
||||
|
||||
// declare functions
|
||||
static int is_selected(size_t index);
|
||||
|
@ -196,7 +204,10 @@ static void insert(const char *str, ssize_t n);
|
|||
static void cleanup(void);
|
||||
static void navigatehistfile(int dir);
|
||||
static void pastesel(void);
|
||||
static void resizeclient(void);
|
||||
static void get_width(void);
|
||||
static void grabfocus(void);
|
||||
static void handle(void);
|
||||
static void appenditem(struct item *item, struct item **list, struct item **last);
|
||||
static int max_textw(void);
|
||||
static size_t nextrune(int inc);
|
||||
|
@ -240,6 +251,7 @@ static char *fonts[] = { font };
|
|||
|
||||
// include x11 code
|
||||
#include "libs/x11/inc.c"
|
||||
#include "libs/wl/inc.c"
|
||||
|
||||
// include more functions
|
||||
#include "libs/history.c"
|
||||
|
@ -348,17 +360,17 @@ void cleanup(void) {
|
|||
cleanupimage(); // function frees images
|
||||
#endif
|
||||
|
||||
// free color scheme
|
||||
for (i = 0; i < LENGTH(colors) + 1; i++)
|
||||
free(scheme[i]);
|
||||
|
||||
// free high priority items
|
||||
for (i = 0; i < hplength; ++i)
|
||||
free(hpitems[i]);
|
||||
|
||||
// free drawing and close the display
|
||||
drw_free(drw);
|
||||
|
||||
if (!protocol) {
|
||||
cleanup_x11(dpy);
|
||||
}
|
||||
|
||||
free(sel_index);
|
||||
}
|
||||
|
||||
|
@ -418,42 +430,82 @@ size_t nextrune(int inc) {
|
|||
}
|
||||
|
||||
void pastesel(void) {
|
||||
if (!protocol) {
|
||||
pastesel_x11();
|
||||
}
|
||||
}
|
||||
|
||||
void resizeclient(void) {
|
||||
#if USEWAYLAND
|
||||
if (protocol) {
|
||||
resizeclient_wl(&state);
|
||||
} else {
|
||||
resizeclient_x11();
|
||||
}
|
||||
#else
|
||||
resizeclient_x11();
|
||||
#endif
|
||||
}
|
||||
|
||||
void get_width(void) {
|
||||
inputw = mw / 3;
|
||||
}
|
||||
|
||||
void handle(void) {
|
||||
if (!protocol) {
|
||||
handle_x11();
|
||||
|
||||
if (!drw_font_create(drw, fonts, LENGTH(fonts))) {
|
||||
die("no fonts could be loaded.");
|
||||
}
|
||||
|
||||
loadhistory(); // read history entries
|
||||
store_image_vars();
|
||||
|
||||
// fast (-f) means we grab keyboard before reading standard input
|
||||
if (fast && !isatty(0)) {
|
||||
grabkeyboard_x11();
|
||||
readstdin();
|
||||
} else {
|
||||
readstdin();
|
||||
grabkeyboard_x11();
|
||||
}
|
||||
|
||||
set_mode();
|
||||
|
||||
init_appearance(); // init colorschemes by reading arrays
|
||||
setupdisplay_x11(); // set up display and create window
|
||||
eventloop_x11(); // function is a loop which checks X11 events and calls other functions accordingly
|
||||
#if USEWAYLAND
|
||||
} else {
|
||||
loadhistory();
|
||||
store_image_vars();
|
||||
|
||||
drw = drw_create_wl(protocol);
|
||||
|
||||
if (!drw_font_create(drw, fonts, LENGTH(fonts))) {
|
||||
die("no fonts could be loaded.");
|
||||
}
|
||||
|
||||
readstdin();
|
||||
set_mode();
|
||||
init_appearance();
|
||||
|
||||
handle_wl();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
readargs(argc, argv); // start by reading arguments
|
||||
|
||||
// open x11 display and create drawable
|
||||
handle_x11();
|
||||
|
||||
// load fonts
|
||||
if (!drw_font_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
|
||||
// pledge limits what programs can do, so here we specify what spmenu should be allowed to do
|
||||
#ifdef __OpenBSD__
|
||||
if (pledge("stdio rpath wpath cpath", NULL) == -1)
|
||||
die("pledge");
|
||||
#endif
|
||||
|
||||
loadhistory(); // read history entries
|
||||
|
||||
// fast (-f) means we grab keyboard before reading standard input
|
||||
if (fast && !isatty(0)) {
|
||||
grabkeyboard();
|
||||
readstdin();
|
||||
} else {
|
||||
readstdin();
|
||||
grabkeyboard();
|
||||
}
|
||||
|
||||
store_image_vars();
|
||||
set_mode();
|
||||
|
||||
init_appearance(); // init colorschemes by reading arrays
|
||||
setupdisplay(); // set up display and create window
|
||||
eventloop(); // function is a loop which checks X11 events and calls other functions accordingly
|
||||
handle();
|
||||
|
||||
return 1; // should be unreachable
|
||||
}
|
||||
|
|
51
spmenu.html
51
spmenu.html
|
@ -169,9 +169,9 @@
|
|||
<h1 class="title">spmenu man page</h1>
|
||||
</header>
|
||||
<h1 id="spmenu">spmenu</h1>
|
||||
<p>spmenu is an X11 menu application which takes standard input, parses
|
||||
it, and lets the user choose an option and sends the selected option to
|
||||
standard output.</p>
|
||||
<p>spmenu is an X11 and Wayland menu application which takes standard
|
||||
input, parses it, lets the user choose an option and sends the selected
|
||||
option to standard output.</p>
|
||||
<p>In addition to this, it also serves as a run launcher through the
|
||||
included shell script <code>spmenu_run</code>, which handles both $PATH
|
||||
listing, .desktop entries and file listing. See spmenu_run(1) for more
|
||||
|
@ -179,6 +179,7 @@ information related to using spmenu as a run launcher.</p>
|
|||
<p>While spmenu is based on dmenu, and is also fully compatible with
|
||||
dmenu, spmenu introduces many new features which can be useful in shell
|
||||
scripting.</p>
|
||||
<p>It also serves as a dmenu replacement for Wayland users.</p>
|
||||
<h2 id="usage">Usage</h2>
|
||||
<p>On runtime, spmenu reads from standard input (stdin). spmenu items
|
||||
are separated by a newline (<code>\n</code>). When (by default) Enter is
|
||||
|
@ -222,14 +223,6 @@ Set max image cache size to size
|
|||
<dd>
|
||||
Set cache directory to dir
|
||||
</dd>
|
||||
<dt><code>-rw, --relative-width</code></dt>
|
||||
<dd>
|
||||
Enable relative input width
|
||||
</dd>
|
||||
<dt><code>-nrw, --no-relative-width</code></dt>
|
||||
<dd>
|
||||
Disable relative input width
|
||||
</dd>
|
||||
<dt><code>-ix, --print-index</code></dt>
|
||||
<dd>
|
||||
Print index instead of actual text
|
||||
|
@ -635,6 +628,14 @@ Load theme (~/.config/spmenu/theme.conf) on runtime
|
|||
<dd>
|
||||
Don’t load theme (~/.config/spmenu/theme.conf) on runtime
|
||||
</dd>
|
||||
<dt><code>-x11, --x11</code></dt>
|
||||
<dd>
|
||||
Run spmenu in X11 mode
|
||||
</dd>
|
||||
<dt><code>-wl, --wayland</code></dt>
|
||||
<dd>
|
||||
Run spmenu in Wayland mode
|
||||
</dd>
|
||||
<dt><code>-v, --version</code></dt>
|
||||
<dd>
|
||||
Print spmenu version to stdout
|
||||
|
@ -1472,6 +1473,7 @@ a <code>keybinds.h</code> using
|
|||
</tbody>
|
||||
</table>
|
||||
<h2 id="xresources">.Xresources</h2>
|
||||
<p><strong>NOTE: Only applies for X11 users</strong></p>
|
||||
<p>spmenu also has .Xresources (xrdb) support built in. It reads the
|
||||
xrdb (.Xresources database) on runtime. You may disable it by passing
|
||||
-nxrdb, or enable it by padding -xrdb. You can also set this in the
|
||||
|
@ -1543,6 +1545,33 @@ Print the spmenu version
|
|||
Print the spmenu license
|
||||
</dd>
|
||||
</dl>
|
||||
<h2 id="wayland-support">Wayland support</h2>
|
||||
<p>Note that Wayland support is still experimental, and some features do
|
||||
not currently work under Wayland. Some will never work under Wayland due
|
||||
to limitations. These are:</p>
|
||||
<ul>
|
||||
<li>Image support
|
||||
<ul>
|
||||
<li>Images simply will not be drawn on Wayland.</li>
|
||||
<li>Will eventually be solved by replacing imlib2 with cairo.</li>
|
||||
</ul></li>
|
||||
<li><code>--x-position</code> and <code>--y-position</code> arguments
|
||||
<ul>
|
||||
<li>These arguments do not work under Wayland, because the layer_shell
|
||||
protocol doesn’t allow clients to be placed on a specific position.</li>
|
||||
</ul></li>
|
||||
<li>Embedding <code>-w</code> and window manager managed
|
||||
<code>-wm</code>
|
||||
<ul>
|
||||
<li>These arguments do not make much sense on Wayland, and embedding is
|
||||
not possible due to the original implementation using XEmbed. If the
|
||||
embed argument is passed it will simply be ignored and the window will
|
||||
be layered as normal.</li>
|
||||
</ul></li>
|
||||
<li><code>--monitor</code> argument</li>
|
||||
<li>Window borders</li>
|
||||
<li>Pasting</li>
|
||||
</ul>
|
||||
<h2 id="license">License</h2>
|
||||
<p>spmenu is licensed under the MIT license because that’s the original
|
||||
suckless license. See the included LICENSE file for more
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
. ftr VB CB
|
||||
. ftr VBI CBI
|
||||
.\}
|
||||
.TH "spmenu_run" "1" "" "1.2.1" "$PATH/.desktop launcher and file manager"
|
||||
.TH "spmenu_run" "1" "" "2.0" "$PATH/.desktop launcher and file manager"
|
||||
.hy
|
||||
.SH spmenu_run
|
||||
.PP
|
||||
|
|
Loading…
Reference in a new issue