Merge remote-tracking branch 'upstream/next' into wayland
This commit is contained in:
57
.github/ISSUE_TEMPLATE/bug_report.md
vendored
57
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,57 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: rofi might be misbehaving
|
||||
labels: bug
|
||||
title: "[BUG] "
|
||||
assignees: ''
|
||||
---
|
||||
:exclamation:
|
||||
First read the [guidelines](https://github.com/DaveDavenport/rofi/blob/next/.github/CONTRIBUTING.md)!
|
||||
This is not optional for any report/question. People must be able to understand the full context of the report when reading it, at any time.
|
||||
If you feel like you “just have a simple question”, please consider you’re wrong and still fill the full report.
|
||||
Any report missing these informations will be labeled as “Incomplete Report - Please follow the guidelines” and may not be answered in a timely fashion.
|
||||
|
||||
If you are unsure, please use the
|
||||
[discussion](https://github.com/davatorium/rofi/discussions) forum first. It is
|
||||
easy to upgrade a question to an issue in github.
|
||||
:exclamation:
|
||||
|
||||
## Version
|
||||
|
||||
Output of `rofi -v`
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
Output of `rofi -help` (in a [gist](https://gist.github.com/), please paste the *full* output)
|
||||
|
||||
|
||||
## Launch Command
|
||||
|
||||
`The commandline used to launch **rofi**`
|
||||
|
||||
|
||||
## Steps to reproduce
|
||||
|
||||
- Step 1
|
||||
- Step 2
|
||||
|
||||
|
||||
## What behaviour you see
|
||||
|
||||
- ...
|
||||
|
||||
|
||||
## What behaviour you expect to see
|
||||
|
||||
- ...
|
||||
|
||||
|
||||
**Additional details:**
|
||||
- Include a link to your private config
|
||||
- Include screenshots/casts of your issue
|
||||
|
||||
|
||||
**Please do not submit reports related to wayland, see
|
||||
[here](https://github.com/DaveDavenport/rofi/wiki/Wayland) for more
|
||||
information.**
|
65
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
65
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
name: Bug Report
|
||||
description: Report a problem in Rofi
|
||||
labels: [bug]
|
||||
title: "[BUG] "
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
First read the [guidelines](https://github.com/DaveDavenport/rofi/blob/next/.github/CONTRIBUTING.md)! This is not optional for any report/question. People must be able to understand the full context of the report when reading it, at any time.
|
||||
|
||||
If you feel like you “just have a simple question”, please consider you’re wrong and still fill the full report. Any report missing these informations will be labeled as “Incomplete Report - Please follow the guidelines” and may not be answered in a timely fashion.
|
||||
|
||||
If you are unsure, please use the [discussion](https://github.com/davatorium/rofi/discussions) forum first. It is easy to upgrade a question to an issue in github.
|
||||
|
||||
**Please do not submit reports related to wayland, see [here](https://github.com/DaveDavenport/rofi/wiki/Wayland) for more information.**
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Rofi version (rofi -v)"
|
||||
placeholder: "Version: 1.6.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Configuration"
|
||||
description: "Please use https://gist.github.com and include output of `rofi -dump-config` and `rofi -dump-theme`."
|
||||
placeholder: "Gist URL"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Launch command"
|
||||
placeholder: "rofi -show drun"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Step to reproduce"
|
||||
placeholder: |
|
||||
* Step 1
|
||||
* Step 2
|
||||
* ...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Expected behavior"
|
||||
description: "Describe the behavior you expect. May include logs, images, or videos."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Actual behavior"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Additional information"
|
||||
validations:
|
||||
required: false
|
||||
|
||||
|
62
.github/ISSUE_TEMPLATE/feature_request.md
vendored
62
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,62 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: It'd be cool if rofi did/had/would...
|
||||
labels: Feature Request
|
||||
title: "[REQUEST] "
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
:exclamation:
|
||||
First read the [guidelines](https://github.com/DaveDavenport/rofi/blob/next/.github/CONTRIBUTING.md)!
|
||||
This is not optional for any report/question. People must be able to understand the full context of the report when reading it, at any time.
|
||||
If you feel like you “just have a simple question”, please consider you’re wrong and still fill the full report.
|
||||
Any report missing these informations will be labeled as “Incomplete Report - Please follow the guidelines” and may not be answered in a timely fashion.
|
||||
|
||||
If you are unsure, please use the
|
||||
[discussion](https://github.com/davatorium/rofi/discussions) forum first. It is
|
||||
easy to upgrade a question to a feature request in github.
|
||||
:exclamation:
|
||||
|
||||
## Before creating a feature request
|
||||
|
||||
- [ ] I checked the *next* branch to see if the feature has already been
|
||||
implemented
|
||||
|
||||
- [ ] I searched existing reports to see if it is already requested.
|
||||
|
||||
|
||||
## What is the user problem or growth opportunity you want to see solved?
|
||||
|
||||
...
|
||||
|
||||
|
||||
## How do you know that this problem exists today? Why is this important?
|
||||
|
||||
...
|
||||
|
||||
|
||||
## Who will benefit from it?
|
||||
|
||||
...
|
||||
|
||||
|
||||
## Version
|
||||
|
||||
Output of `rofi -v`
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
Output of `rofi -help` (in a [gist](https://gist.github.com/), please paste the *full* output)
|
||||
|
||||
|
||||
**Additional details:**
|
||||
- Include a link to your private config
|
||||
- Include screenshots/casts of your issue
|
||||
|
||||
**Please do not submit reports related to wayland, see
|
||||
[here](https://github.com/DaveDavenport/rofi/wiki/Wayland) for more
|
||||
information.**
|
||||
|
||||
|
||||
**Requesting a feature is no guarantee it will be added.**
|
62
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
62
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Feature Request
|
||||
description: It'd be cool if rofi did/had/would...
|
||||
labels: Feature Request
|
||||
title: "[REQUEST] "
|
||||
body:
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
First read the [guidelines](https://github.com/DaveDavenport/rofi/blob/next/.github/CONTRIBUTING.md)! This is not optional for any report/question. People must be able to understand the full context of the report when reading it, at any time.
|
||||
|
||||
If you feel like you “just have a simple question”, please consider you’re wrong and still fill the full report. Any report missing these informations will be labeled as “Incomplete Report - Please follow the guidelines” and may not be answered in a timely fashion.
|
||||
|
||||
If you are unsure, please use the [discussion](https://github.com/davatorium/rofi/discussions) forum first. It is easy to upgrade a question to an issue in github.
|
||||
|
||||
**Please do not submit reports related to wayland, see [here](https://github.com/DaveDavenport/rofi/wiki/Wayland) for more information.**
|
||||
|
||||
**Requesting a feature is no guarantee it will be added.**
|
||||
|
||||
- type: checkboxes
|
||||
id: before-feature-request
|
||||
attributes:
|
||||
label: Before opening a feature request
|
||||
options:
|
||||
- label: I checked the *next* branch to see if the feature has already been implemented
|
||||
required: true
|
||||
- label: I searched existing reports to see if it is already requested.
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "What is the user problem or growth opportunity you want to see solved?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "How do you know that this problem exists today? Why is this important?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Who will benefit from it?"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Rofi version (rofi -v)"
|
||||
placeholder: "Version: 1.6.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Configuration"
|
||||
description: "Please use https://gist.github.com and include output of `rofi -dump-config` and `rofi -dump-theme`."
|
||||
placeholder: "Gist URL"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Additional information"
|
||||
validations:
|
||||
required: false
|
||||
|
11
.github/actions/autotools/action.yml
vendored
11
.github/actions/autotools/action.yml
vendored
@@ -9,6 +9,9 @@ inputs:
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- id: pip
|
||||
run: pip install meson ninja
|
||||
shell: bash
|
||||
- id: setup
|
||||
run: |
|
||||
autoreconf --install
|
||||
@@ -30,6 +33,14 @@ runs:
|
||||
uses: ./.github/actions/doxycheck
|
||||
with:
|
||||
logfile: builddir/doxygen.log
|
||||
- id: meson-dist-check
|
||||
shell: bash
|
||||
run: |
|
||||
tar xf builddir/rofi-*.tar.gz
|
||||
cd rofi-*/
|
||||
meson setup . build
|
||||
ninja -C build
|
||||
ninja -C build test
|
||||
- id: upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
|
@@ -6,7 +6,8 @@ then
|
||||
exit
|
||||
fi
|
||||
|
||||
echo -en "\x00no-custom\x1ftrue\n"
|
||||
echo -en "\x00no-custom\x1ffalse\n"
|
||||
echo -en "\x00use-hot-keys\x1ftrue\n"
|
||||
echo -en "${ROFI_RETV}\x00icon\x1ffirefox\x1finfo\x1ftest\n"
|
||||
|
||||
if [ -n "${ROFI_INFO}" ]
|
||||
|
46
Makefile.am
46
Makefile.am
@@ -186,23 +186,6 @@ EXTRA_DIST += \
|
||||
doc/rofi-sensible-terminal.1.markdown \
|
||||
doc/rofi.1.markdown
|
||||
|
||||
##
|
||||
# Readme.md
|
||||
##
|
||||
markdown_SC_FILES=\
|
||||
README.md
|
||||
|
||||
# want the html to show up in release.
|
||||
md_verbose = $(md_verbose_@AM_V@)
|
||||
md_verbose_ = $(md_verbose_@AM_DEFAULT_V@)
|
||||
md_verbose_0 = @echo " MD" $@;
|
||||
|
||||
markdown_FILES=\
|
||||
README.html
|
||||
|
||||
README.html: README.md
|
||||
$(md_verbose) markdown $< > $@
|
||||
|
||||
###
|
||||
# Themes
|
||||
###
|
||||
@@ -245,7 +228,6 @@ theme_DATA=\
|
||||
##
|
||||
EXTRA_DIST+=\
|
||||
$(markdown_FILES)\
|
||||
$(markdown_SC_FILES)\
|
||||
Examples/i3_switch_workspaces.sh\
|
||||
Examples/i3_empty_workspace.sh\
|
||||
Examples/test_script_mode.sh\
|
||||
@@ -348,6 +330,7 @@ helper_pidfile_SOURCES=\
|
||||
include/mode-private.h\
|
||||
source/helper.c\
|
||||
source/theme.c\
|
||||
source/css-colors.c\
|
||||
source/rofi-types.c\
|
||||
include/rofi-types.h\
|
||||
include/helper.h\
|
||||
@@ -468,6 +451,7 @@ helper_test_SOURCES=\
|
||||
include/xrmoptions.h\
|
||||
source/xrmoptions.c\
|
||||
source/theme.c\
|
||||
source/css-colors.c\
|
||||
source/rofi-types.c\
|
||||
include/rofi-types.h\
|
||||
test/helper-test.c
|
||||
@@ -505,6 +489,7 @@ helper_expand_SOURCES=\
|
||||
include/mode-private.h\
|
||||
source/helper.c\
|
||||
source/theme.c\
|
||||
source/css-colors.c\
|
||||
include/helper.h\
|
||||
include/helper-theme.h\
|
||||
include/xrmoptions.h\
|
||||
@@ -527,6 +512,7 @@ helper_config_cmdline_parser_SOURCES=\
|
||||
include/mode-private.h\
|
||||
source/helper.c\
|
||||
source/theme.c\
|
||||
source/css-colors.c\
|
||||
source/rofi-types.c\
|
||||
include/rofi-types.h\
|
||||
include/helper.h\
|
||||
@@ -544,7 +530,8 @@ mode_test_SOURCES=\
|
||||
source/dialogs/help-keys.c\
|
||||
source/helper.c\
|
||||
source/theme.c\
|
||||
source/mode.c\
|
||||
source/css-colors.c\
|
||||
source/mode.c\
|
||||
source/rofi-types.c\
|
||||
include/rofi-types.h\
|
||||
source/xrmoptions.c\
|
||||
@@ -560,6 +547,7 @@ helper_tokenize_SOURCES=\
|
||||
include/mode-private.h\
|
||||
source/helper.c\
|
||||
source/theme.c\
|
||||
source/css-colors.c\
|
||||
source/rofi-types.c\
|
||||
include/rofi-types.h\
|
||||
include/helper.h\
|
||||
@@ -630,8 +618,26 @@ coverage-clean:
|
||||
|
||||
EXTRA_DIST += \
|
||||
doc/meson.build \
|
||||
subprojects/libgwater/mpd/meson.build \
|
||||
subprojects/libgwater/nl/meson.build \
|
||||
subprojects/libgwater/wayland/meson.build \
|
||||
subprojects/libgwater/xcb/meson.build \
|
||||
subprojects/libgwater/alsa-mixer/meson.build \
|
||||
subprojects/libgwater/wayland-server/meson.build \
|
||||
subprojects/libgwater/meson.build \
|
||||
subprojects/libgwater/win/meson.build \
|
||||
subprojects/libnkutils/meson.build \
|
||||
subprojects/libnkutils/meson_options.txt \
|
||||
subprojects/libgwater/xcb/meson.build \
|
||||
subprojects/libgwater/wayland/libgwater-wayland.h \
|
||||
subprojects/libgwater/wayland/libgwater-wayland.c \
|
||||
subprojects/libgwater/wayland-server/libgwater-wayland-server.c \
|
||||
subprojects/libgwater/wayland-server/libgwater-wayland-server.h \
|
||||
subprojects/libgwater/mpd/libgwater-mpd.h \
|
||||
subprojects/libgwater/mpd/libgwater-mpd.c \
|
||||
subprojects/libgwater/nl/libgwater-nl.h \
|
||||
subprojects/libgwater/nl/libgwater-nl.c \
|
||||
subprojects/libgwater/alsa-mixer/libgwater-alsa-mixer.h \
|
||||
subprojects/libgwater/alsa-mixer/libgwater-alsa-mixer.c \
|
||||
doc/meson_build_manpages.sh \
|
||||
meson_options.txt \
|
||||
meson.build
|
||||
|
@@ -1,4 +1,4 @@
|
||||
AC_INIT([rofi], [1.7.0], [https://github.com/davatorium/rofi/],[],[https://reddit.com/r/qtools/])
|
||||
AC_INIT([rofi], [1.7.0-dev], [https://github.com/davatorium/rofi/],[],[https://reddit.com/r/qtools/])
|
||||
|
||||
AC_CONFIG_SRCDIR([source/rofi.c])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
|
@@ -2,15 +2,15 @@
|
||||
|
||||
In the current theme format you set these properties on the `window` widget.
|
||||
|
||||
The first, position, determines where **rofi** is placed on the monitor, the
|
||||
The first, location, determines where **rofi** is placed on the monitor, the
|
||||
second what point of the **rofi** window connects there. This sounds
|
||||
complicated, but it ain't.
|
||||
|
||||
## position setting
|
||||
## location setting
|
||||
|
||||
The position setting determines the place of the window on the monitor.
|
||||
The location setting determines the place of the window on the monitor.
|
||||
|
||||
The position setting supports the following values:
|
||||
The location setting supports the following values:
|
||||
|
||||
* north
|
||||
* northeast
|
||||
@@ -24,25 +24,25 @@ The position setting supports the following values:
|
||||
|
||||
This is depicted in the diagram below:
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
## anchor setting
|
||||
|
||||
The anchor sets what point of the **rofi** window is placed at the specified *position*.
|
||||
The anchor sets what point of the **rofi** window is placed at the specified *location*.
|
||||
|
||||
The *anchor* settings supports the same values as the *position* setting.
|
||||
The *anchor* settings supports the same values as the *location* setting.
|
||||
|
||||
If you want the middle of the **rofi** window to be always located at the center of the monitor set both *position* and
|
||||
If you want the middle of the **rofi** window to be always located at the center of the monitor set both *location* and
|
||||
*anchor* to `center`.
|
||||
|
||||
If the **rofi** window resizes, its center will stay at the center.
|
||||
If you set the *anchor* to `north` the top of the **rofi** window is at the center of the monitor, and the window will grow
|
||||
down.
|
||||
|
||||
If you set the *anchor* and *position* to `south`, **rofi** is located at the bottom center and the window grows up.
|
||||
If you set the *anchor* and *location* to `south`, **rofi** is located at the bottom center and the window grows up.
|
||||
|
||||
> Note that if you set the *anchor* to `south` and the *position* to `north` the **rofi** window will be placed above
|
||||
> Note that if you set the *anchor* to `south` and the *location* to `north` the **rofi** window will be placed above
|
||||
> the monitor and might not be visible.
|
||||
|
||||
|
||||
@@ -52,17 +52,17 @@ So the following theme setting will place the top of the **rofi** window in the
|
||||
|
||||
```css
|
||||
window {
|
||||
position: center;
|
||||
location: center;
|
||||
anchor: north;
|
||||
}
|
||||
```
|
||||
|
||||
As depicted here, RED is the position (center of screen), GREEN is the position on **rofi** window (north):
|
||||
As depicted here, RED is the location (center of screen), GREEN is the anchor on **rofi** window (north):
|
||||
|
||||

|
||||
|
||||
> Quick hint, if you want to quickly test out changes to the theme, without editing the file, run **rofi** like:
|
||||
|
||||
```bash
|
||||
rofi -show run -theme-str "window { position: center; anchor: north;}"
|
||||
rofi -show run -theme-str "window { location: center; anchor: north;}"
|
||||
```
|
||||
|
@@ -1,3 +1,4 @@
|
||||
.nh
|
||||
.TH ROFI\-SCRIPT 5 rofi\-script
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -193,20 +194,20 @@ rofi(1), rofi\-sensible\-terminal(1), dmenu(1), rofi\-theme(5), rofi\-theme\-sel
|
||||
|
||||
.SH AUTHOR
|
||||
.PP
|
||||
Qball Cow
|
||||
\[la]qball@gmpclient.org\[ra]
|
||||
Qball Cow qball@gmpclient.org
|
||||
\[la]mailto:qball@gmpclient.org\[ra]
|
||||
|
||||
.PP
|
||||
Rasmus Steinke
|
||||
\[la]rasi@xssn.at\[ra]
|
||||
Rasmus Steinke rasi@xssn.at
|
||||
\[la]mailto:rasi@xssn.at\[ra]
|
||||
|
||||
.PP
|
||||
Quentin Glidic
|
||||
\[la]sardemff7+rofi@sardemff7.net\[ra]
|
||||
Quentin Glidic sardemff7+rofi@sardemff7.net
|
||||
\[la]mailto:sardemff7+rofi@sardemff7.net\[ra]
|
||||
|
||||
.PP
|
||||
Original code based on work by: Sean Pringle
|
||||
\[la]sean.pringle@gmail.com\[ra]
|
||||
Original code based on work by: Sean Pringle sean.pringle@gmail.com
|
||||
\[la]mailto:sean.pringle@gmail.com\[ra]
|
||||
|
||||
.PP
|
||||
For a full list of authors, check the AUTHORS file.
|
||||
|
@@ -1,3 +1,4 @@
|
||||
.nh
|
||||
.TH rofi\-sensible\-terminal 1 rofi\-sensible\-terminal
|
||||
.SH NAME
|
||||
.PP
|
||||
|
@@ -1,3 +1,4 @@
|
||||
.nh
|
||||
.TH rofi\-theme\-selector 1 rofi\-theme\-selector
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -30,8 +31,8 @@ $XDG\_DATA\_HOME/share/rofi/themes
|
||||
.RE
|
||||
|
||||
.PP
|
||||
${PREFIX} reflects the install location of rofi. In most cases this will be "/usr".<br>
|
||||
$XDG\_CONFIG\_HOME is normally unset. Default path is "$HOME/.config".<br>
|
||||
${PREFIX} reflects the install location of rofi. In most cases this will be "/usr".
|
||||
$XDG\_CONFIG\_HOME is normally unset. Default path is "$HOME/.config".
|
||||
$XDG\_DATA\_HOME is normally unset. Default path is "$HOME/.local/share".
|
||||
|
||||
.SH SEE ALSO
|
||||
@@ -40,5 +41,5 @@ rofi(1)
|
||||
|
||||
.SH AUTHORS
|
||||
.PP
|
||||
Qball Cow qball@gmpclient.org<br>
|
||||
Qball Cow qball@gmpclient.org
|
||||
Rasmus Steinke rasi@xssn.at
|
||||
|
150
doc/rofi-theme.5
150
doc/rofi-theme.5
@@ -1,8 +1,47 @@
|
||||
.nh
|
||||
.TH ROFI\-THEME 5 rofi\-theme
|
||||
.SH NAME
|
||||
.PP
|
||||
\fBrofi\-theme\fP \- Rofi theme format files
|
||||
|
||||
.SH DEFAULT THEME LOADING
|
||||
.PP
|
||||
By default, rofi loads the default theme. This theme is \fBalways\fP loaded.
|
||||
In the default (always loaded) configuration it does:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
@theme "default"
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
To unload the default theme, and load another theme, add \fB\fC@theme\fR to your
|
||||
\fB\fCconfig.rasi\fR file.
|
||||
|
||||
.PP
|
||||
If you have a theme loaded by \fB\fC@theme\fR or use the default theme, you can tweak
|
||||
it by adding overriding elements at the end of your \fB\fCconfig.rasi\fR file.
|
||||
|
||||
.PP
|
||||
For the difference between \fB\fC@import\fR and \fB\fC@theme\fR see the \fB\fCMultiple file
|
||||
handling\fR section in this manpage.
|
||||
|
||||
.PP
|
||||
To see the default theme, run the following command:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
rofi \-no\-config \-dump\-theme
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The need for a new theme format was motivated by the fact that the way rofi handled widgets has changed. From a very
|
||||
@@ -95,7 +134,7 @@ abbreviation for \fBr\fPofi \fBa\fPdvanced \fBs\fPtyle \fBi\fPnformation.
|
||||
.SH Basic Structure
|
||||
.PP
|
||||
Each element has a section with defined properties. Global properties can be defined in section \fB\fC* { }\fR\&.
|
||||
Sub\-section names begin with a hash symbol \fB\fC#\fR\&.
|
||||
Sub\-\§ion names begin with a hash symbol \fB\fC#\fR\&.
|
||||
|
||||
.PP
|
||||
It is advised to define the \fIglobal properties section\fP on top of the file to
|
||||
@@ -452,11 +491,7 @@ The different values are:
|
||||
.IP \(bu 2
|
||||
\fB\fC{PERCENTAGE}\fR can be between 0\-1.0, or 0%\-100%
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fB\fC{named\-color}\fR is one of the following colors:
|
||||
.PP
|
||||
AliceBlue, AntiqueWhite, Aqua, Aquamarine, Azure, Beige, Bisque, Black, BlanchedAlmond, Blue, BlueViolet, Brown,
|
||||
\fB\fC{named\-color}\fR is one of the following colors:AliceBlue, AntiqueWhite, Aqua, Aquamarine, Azure, Beige, Bisque, Black, BlanchedAlmond, Blue, BlueViolet, Brown,
|
||||
BurlyWood, CadetBlue, Chartreuse, Chocolate, Coral, CornflowerBlue, Cornsilk, Crimson, Cyan, DarkBlue, DarkCyan,
|
||||
DarkGoldenRod, DarkGray, DarkGrey, DarkGreen, DarkKhaki, DarkMagenta, DarkOliveGreen, DarkOrange, DarkOrchid, DarkRed,
|
||||
DarkSalmon, DarkSeaGreen, DarkSlateBlue, DarkSlateGray, DarkSlateGrey, DarkTurquoise, DarkViolet, DeepPink, DeepSkyBlue,
|
||||
@@ -688,6 +723,7 @@ style property.
|
||||
|
||||
.PP
|
||||
When no unit is specified, pixels are assumed.
|
||||
|
||||
.RE
|
||||
|
||||
.SH Position
|
||||
@@ -696,22 +732,14 @@ Indicate a place on the window/monitor.
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
Format: \fB\fC(center|east|north|west|south|north east|north west|south west|south east)\fR
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
|
||||
\fB\fC
|
||||
north west | north | north east
|
||||
\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-
|
||||
west | center | east
|
||||
\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-
|
||||
south west | south | south east
|
||||
|
||||
.fi
|
||||
.RE
|
||||
\fR
|
||||
|
||||
.RE
|
||||
|
||||
@@ -763,6 +791,34 @@ window {
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
Format: \fB\fCvar(PROPERTY NAME, DEFAULT)\fR
|
||||
|
||||
.RE
|
||||
|
||||
.PP
|
||||
A reference can point to another reference. Currently, the maximum number of redirects is 20.
|
||||
A property always refers to another property. It cannot be used for a subpart of the property.
|
||||
|
||||
.PP
|
||||
Example:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
window {
|
||||
width: var( width, 30%);
|
||||
}
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
If the property \fB\fCwidth\fR is set globally (\fB\fC*{}\fR) that value is used, if the property
|
||||
\fB\fCwidth\fR is not set, the default value is used.
|
||||
|
||||
.SH Orientation
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
@@ -816,6 +872,31 @@ The environment variable should be an alphanumeric string without white\-space.
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
Format: \fB\fCenv(ENVIRONMENT, default)\fR
|
||||
|
||||
.RE
|
||||
|
||||
.PP
|
||||
This will parse the environment variable as the property value. (that then can be any of the above types).
|
||||
The environment variable should be an alphanumeric string without white\-space.
|
||||
If the environment value is not found, the default value is used.
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
window {
|
||||
width: env(WIDTH, 40%);
|
||||
}
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
If environment WIDTH is set, then that value is parsed, otherwise the default value (\fB\fC40%\fR).
|
||||
|
||||
.SH Inherit
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
@@ -883,7 +964,6 @@ The current widgets available in \fBrofi\fP:
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCwindow\fR
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCoverlay\fR: the overlay widget.
|
||||
@@ -891,7 +971,6 @@ The current widgets available in \fBrofi\fP:
|
||||
\fB\fCmainbox\fR: The mainbox box.
|
||||
.IP \(bu 2
|
||||
\fB\fCinputbar\fR: The input bar box.
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCbox\fR: the horizontal @box packing the widgets
|
||||
@@ -907,15 +986,14 @@ The current widgets available in \fBrofi\fP:
|
||||
\fB\fCnum\-filtered\-rows\fR: Shows the total number of rows after filtering.
|
||||
|
||||
.RE
|
||||
|
||||
.IP \(bu 2
|
||||
\fB\fClistview\fR: The listview.
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCscrollbar\fR: the listview scrollbar
|
||||
.IP \(bu 2
|
||||
\fB\fCelement\fR: a box in the listview holding the entries
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCelement\-icon\fR: the widget in the listview's entry showing the (optional) icon
|
||||
@@ -926,26 +1004,29 @@ The current widgets available in \fBrofi\fP:
|
||||
|
||||
.RE
|
||||
|
||||
|
||||
.RE
|
||||
|
||||
.IP \(bu 2
|
||||
\fB\fCmode\-switcher\fR: the main horizontal @box packing the buttons.
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCbutton\fR: the buttons @textbox for each mode
|
||||
|
||||
.RE
|
||||
|
||||
.IP \(bu 2
|
||||
\fB\fCmessage\fR: The container holding the textbox.
|
||||
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
\fB\fCtextbox\fR: the message textbox
|
||||
|
||||
.RE
|
||||
|
||||
|
||||
.RE
|
||||
|
||||
|
||||
.RE
|
||||
|
||||
.PP
|
||||
@@ -1053,13 +1134,9 @@ Type of mouse cursor that is set when the mouse pointer is hovered over the widg
|
||||
.SS window:
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBfont\fP: string
|
||||
The font used in the window
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBtransparency\fP: string
|
||||
Indicating if transparency should be used and what type:
|
||||
\fBreal\fP \- True transparency. Only works with a compositor.
|
||||
@@ -1067,32 +1144,20 @@ Indicating if transparency should be used and what type:
|
||||
\fBscreenshot\fP \- Take a screenshot of the screen and use that.
|
||||
\fBPath\fP to png file \- Use an image.
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBlocation\fP: position
|
||||
The place of the anchor on the monitor
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBanchor\fP: anchor
|
||||
The anchor position on the window
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBfullscreen\fP: boolean
|
||||
Window is fullscreen.
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBwidth\fP: distance
|
||||
The width of the window
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBx\-offset\fP: distance
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBy\-offset\fP: distance
|
||||
The offset of the window to the anchor point, allowing you to push the window left/right/up/down
|
||||
|
||||
@@ -1272,6 +1337,12 @@ The current layout of \fBrofi\fP is structured as follows:
|
||||
| | | |
|
||||
| | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |
|
||||
| | | listview | |
|
||||
| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-] | |
|
||||
| | | | element | | |
|
||||
| | | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-] | | |
|
||||
| | | | |element\-icon | |element\-text | | | |
|
||||
| | | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | |
|
||||
| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-] | |
|
||||
| | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |
|
||||
| | | |
|
||||
| | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | |
|
||||
@@ -1314,9 +1385,6 @@ ns is the num\-rows
|
||||
| | error\-message {BOX:vertical} | |
|
||||
| | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | |
|
||||
| | | textbox | | |
|
||||
| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | |
|
||||
| | | |element\-icon | |element\-text | | | |
|
||||
| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | |
|
||||
| | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | |
|
||||
| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |
|
||||
|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-|
|
||||
|
@@ -4,6 +4,30 @@
|
||||
|
||||
**rofi-theme** - Rofi theme format files
|
||||
|
||||
## DEFAULT THEME LOADING
|
||||
|
||||
By default, rofi loads the default theme. This theme is **always** loaded.
|
||||
In the default (always loaded) configuration it does:
|
||||
|
||||
```css
|
||||
@theme "default"
|
||||
```
|
||||
|
||||
To unload the default theme, and load another theme, add `@theme` to your
|
||||
`config.rasi` file.
|
||||
|
||||
If you have a theme loaded by `@theme` or use the default theme, you can tweak
|
||||
it by adding overriding elements at the end of your `config.rasi` file.
|
||||
|
||||
For the difference between `@import` and `@theme` see the `Multiple file
|
||||
handling` section in this manpage.
|
||||
|
||||
To see the default theme, run the following command:
|
||||
|
||||
```bash
|
||||
rofi -no-config -dump-theme
|
||||
```
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
The need for a new theme format was motivated by the fact that the way rofi handled widgets has changed. From a very
|
||||
@@ -470,6 +494,23 @@ window {
|
||||
}
|
||||
```
|
||||
|
||||
* Format: `var(PROPERTY NAME, DEFAULT)`
|
||||
|
||||
A reference can point to another reference. Currently, the maximum number of redirects is 20.
|
||||
A property always refers to another property. It cannot be used for a subpart of the property.
|
||||
|
||||
Example:
|
||||
|
||||
```css
|
||||
window {
|
||||
width: var( width, 30%);
|
||||
}
|
||||
```
|
||||
|
||||
If the property `width` is set globally (`*{}`) that value is used, if the property
|
||||
`width` is not set, the default value is used.
|
||||
|
||||
|
||||
## Orientation
|
||||
|
||||
* Format: `(horizontal|vertical)`
|
||||
@@ -502,6 +543,20 @@ The environment variable should be an alphanumeric string without white-space.
|
||||
}
|
||||
```
|
||||
|
||||
* Format: `env(ENVIRONMENT, default)`
|
||||
|
||||
This will parse the environment variable as the property value. (that then can be any of the above types).
|
||||
The environment variable should be an alphanumeric string without white-space.
|
||||
If the environment value is not found, the default value is used.
|
||||
|
||||
```css
|
||||
window {
|
||||
width: env(WIDTH, 40%);
|
||||
}
|
||||
```
|
||||
|
||||
If environment WIDTH is set, then that value is parsed, otherwise the default value (`40%`).
|
||||
|
||||
## Inherit
|
||||
|
||||
* Format: `inherit`
|
||||
@@ -786,6 +841,12 @@ The current layout of **rofi** is structured as follows:
|
||||
| | | |
|
||||
| | |-----------------------------------------------------------------------------| |
|
||||
| | | listview | |
|
||||
| | | |------------------------------------------------------------------------] | |
|
||||
| | | | element | | |
|
||||
| | | | |-----------------| |------------------------------------------------] | | |
|
||||
| | | | |element-icon | |element-text | | | |
|
||||
| | | | |-----------------| |------------------------------------------------| | | |
|
||||
| | | |------------------------------------------------------------------------] | |
|
||||
| | |-----------------------------------------------------------------------------| |
|
||||
| | | |
|
||||
| | |---------------------------------------------------------------------------| | |
|
||||
@@ -812,9 +873,6 @@ The current layout of **rofi** is structured as follows:
|
||||
| | error-message {BOX:vertical} | |
|
||||
| | |-------------------------------------------------------------------------| | |
|
||||
| | | textbox | | |
|
||||
| | | |-----------------| |-------------------------------------------------| | | |
|
||||
| | | |element-icon | |element-text | | | |
|
||||
| | | |-----------------| |-------------------------------------------------| | | |
|
||||
| | |-------------------------------------------------------------------------| | |
|
||||
| |------------------------------------------------------------------------------| |
|
||||
|-----------------------------------------------------------------------------------|
|
||||
@@ -1013,15 +1071,15 @@ This property sets the distance between the packed widgets (both horizontally an
|
||||
More dynamic spacing can be achieved by adding dummy widgets, for example to make one widget centered:
|
||||
|
||||
```
|
||||
|--------------------------------------------|
|
||||
| |-----------| |--------| |-----------| |
|
||||
| | dummy | | child | | dummy | |
|
||||
| | expand: y | | | | expand: y | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| |-----------| |--------| |-----------| |
|
||||
|--------------------------------------------|
|
||||
|----------------------------------------------------|
|
||||
| |---------------| |--------| |---------------| |
|
||||
| | dummy | | child | | dummy | |
|
||||
| | expand: true; | | | | expand: true; | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
| |---------------| |--------| |---------------| |
|
||||
|----------------------------------------------------|
|
||||
```
|
||||
|
||||
If both dummy widgets are set to expand, `child` will be centered. Depending on the `expand` flag of child the
|
||||
|
95
doc/rofi.1
95
doc/rofi.1
@@ -1,3 +1,4 @@
|
||||
.nh
|
||||
.TH ROFI 1 rofi
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -46,7 +47,7 @@ The website for \fB\fCdmenu\fR can be found here
|
||||
|
||||
.PP
|
||||
\fBrofi\fP does not aim to be 100% compatible with \fB\fCdmenu\fR\&. There are simply too many flavors of \fB\fCdmenu\fR\&.
|
||||
The idea is that the basic usage command\-line flags are obeyed, theme\-related flags are not.
|
||||
The idea is that the basic usage command\-\&line flags are obeyed, theme\-\&related flags are not.
|
||||
Besides, \fBrofi\fP offers some extended features (like multi\-select, highlighting, message bar, extra key bindings).
|
||||
|
||||
.SS Display Error message
|
||||
@@ -180,11 +181,7 @@ Specify the number of threads \fBrofi\fP should use:
|
||||
.IP \(bu 2
|
||||
1: Disable threading
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
2..n: Specify the maximum number of threads to use in the thread pool.
|
||||
.PP
|
||||
Default: Autodetect
|
||||
2..n: Specify the maximum number of threads to use in the thread pool.Default: Autodetect
|
||||
|
||||
.RE
|
||||
|
||||
@@ -382,7 +379,7 @@ If not specified default theme from DE is used, \fIAdwaita\fP and \fIgnome\fP th
|
||||
fallback themes.
|
||||
|
||||
.PP
|
||||
\fB\fC\-fallback\-application\-icon\fR
|
||||
\fB\fC\-application\-fallback\-icon\fR
|
||||
|
||||
.PP
|
||||
Specify an icon to be used when the application icon in run/drun are not yet loaded or is not available.
|
||||
@@ -464,11 +461,7 @@ The different fields are:
|
||||
.IP \(bu 2
|
||||
\fBcomment\fP: the application comment
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBall\fP: all the above
|
||||
.PP
|
||||
Default: \fIname,generic,exec,categories,keywords\fP
|
||||
\fBall\fP: all the aboveDefault: \fIname,generic,exec,categories,keywords\fP
|
||||
|
||||
.RE
|
||||
|
||||
@@ -541,11 +534,7 @@ The different fields are:
|
||||
.IP \(bu 2
|
||||
\fBdesktop\fP: window's current desktop
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fBall\fP: all the above
|
||||
.PP
|
||||
Default: \fIall\fP
|
||||
\fBall\fP: all the aboveDefault: \fIall\fP
|
||||
|
||||
.RE
|
||||
|
||||
@@ -602,7 +591,7 @@ Default: \fI0\fP
|
||||
\fB\fC\-fixed\-num\-lines\fR
|
||||
|
||||
.PP
|
||||
Keep a fixed number of visible lines (See the \fB\fC\-lines\fR option.)
|
||||
Keep a fixed number of visible lines.
|
||||
|
||||
.PP
|
||||
\fB\fC\-sidebar\-mode\fR
|
||||
@@ -616,7 +605,7 @@ To show sidebar, use:
|
||||
.RS
|
||||
|
||||
.nf
|
||||
rofi \-show run \-sidebar\-mode \-lines 0
|
||||
rofi \-show run \-sidebar\-mode
|
||||
|
||||
.fi
|
||||
.RE
|
||||
@@ -678,11 +667,7 @@ behavior.)
|
||||
.IP \(bu 2
|
||||
\fB\-4\fP: the monitor with the focused window.
|
||||
.IP \(bu 2
|
||||
|
||||
.PP
|
||||
\fB\-5\fP: the monitor that shows the mouse pointer.
|
||||
.PP
|
||||
Default: \fI\-5\fP
|
||||
\fB\-5\fP: the monitor that shows the mouse pointer.Default: \fI\-5\fP
|
||||
|
||||
.RE
|
||||
|
||||
@@ -1006,7 +991,7 @@ Maximum number of lines the menu may show before scrolling.
|
||||
.RS
|
||||
|
||||
.nf
|
||||
rofi \-lines 25
|
||||
rofi \-dmenu \-l 25
|
||||
|
||||
.fi
|
||||
.RE
|
||||
@@ -1100,7 +1085,7 @@ Select first line that matches the given string
|
||||
.PP
|
||||
Add a message line below the filter entry box. Supports Pango markup.
|
||||
For more information on supported markup, see here
|
||||
\[la]https://developer.gnome.org/pygtk/stable/pango-markup-language.html\[ra]
|
||||
\[la]https://docs.gtk.org/Pango/pango_markup.html\[ra]
|
||||
|
||||
.PP
|
||||
\fB\fC\-dump\fR
|
||||
@@ -1180,7 +1165,7 @@ Set ellipsize mode to start. So, the end of the string is visible.
|
||||
|
||||
.PP
|
||||
Pops up a message dialog (used internally for showing errors) with \fImessage\fP\&.
|
||||
Message can be multi\-line.
|
||||
Message can be multi\-\&line.
|
||||
|
||||
.SS File browser settings
|
||||
.PP
|
||||
@@ -1393,6 +1378,46 @@ To get a searchable list of key bindings, run \fB\fCrofi \-show keys\fR\&.
|
||||
.PP
|
||||
A key binding starting with \fB\fC!\fR will act when all keys have been released.
|
||||
|
||||
.PP
|
||||
You can bind certain events to key\-actions:
|
||||
|
||||
.SS Timeout
|
||||
.PP
|
||||
You can configure an action to be taken when rofi has not been interacted
|
||||
with for a certain amount of seconds. You can specify a keybinding to trigger
|
||||
after X seconds.
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
configuration {
|
||||
timeout {
|
||||
delay: 15;
|
||||
action: "kb\-cancel";
|
||||
}
|
||||
}
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SS Input change
|
||||
.PP
|
||||
When the input of the textbox changes:
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
configuration {
|
||||
inputchange {
|
||||
action: "kb\-row\-first";
|
||||
}
|
||||
}
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.SH Available Modi
|
||||
.SS window
|
||||
.PP
|
||||
@@ -1759,21 +1784,21 @@ first.
|
||||
.SH AUTHOR
|
||||
.RS
|
||||
.IP \(bu 2
|
||||
Qball Cow
|
||||
\[la]qball@blame.services\[ra]
|
||||
Qball Cow qball@blame.services
|
||||
\[la]mailto:qball@blame.services\[ra]
|
||||
.IP \(bu 2
|
||||
Rasmus Steinke
|
||||
\[la]rasi@xssn.at\[ra]
|
||||
Rasmus Steinke rasi@xssn.at
|
||||
\[la]mailto:rasi@xssn.at\[ra]
|
||||
.IP \(bu 2
|
||||
Quentin Glidic
|
||||
\[la]sardemff7+rofi@sardemff7.net\[ra]
|
||||
Quentin Glidic sardemff7+rofi@sardemff7.net
|
||||
\[la]mailto:sardemff7+rofi@sardemff7.net\[ra]
|
||||
|
||||
.RE
|
||||
|
||||
.PP
|
||||
Original code based on work by: Sean Pringle
|
||||
\[la]https://github.com/seanpringle/simpleswitcher\[ra]
|
||||
\[la]sean.pringle@gmail.com\[ra]
|
||||
\[la]https://github.com/seanpringle/simpleswitcher\[ra] sean.pringle@gmail.com
|
||||
\[la]mailto:sean.pringle@gmail.com\[ra]
|
||||
|
||||
.PP
|
||||
For a full list of authors, check the \fB\fCAUTHORS\fR file.
|
||||
|
@@ -222,7 +222,7 @@ Specify icon theme to be used.
|
||||
If not specified default theme from DE is used, *Adwaita* and *gnome* themes act as
|
||||
fallback themes.
|
||||
|
||||
`-fallback-application-icon`
|
||||
`-application-fallback-icon`
|
||||
|
||||
Specify an icon to be used when the application icon in run/drun are not yet loaded or is not available.
|
||||
|
||||
@@ -345,7 +345,7 @@ Default: *0*
|
||||
|
||||
`-fixed-num-lines`
|
||||
|
||||
Keep a fixed number of visible lines (See the `-lines` option.)
|
||||
Keep a fixed number of visible lines.
|
||||
|
||||
`-sidebar-mode`
|
||||
|
||||
@@ -353,7 +353,7 @@ Open in sidebar-mode. In this mode, a list of all enabled modes is shown at the
|
||||
(See `-modi` option)
|
||||
To show sidebar, use:
|
||||
|
||||
rofi -show run -sidebar-mode -lines 0
|
||||
rofi -show run -sidebar-mode
|
||||
|
||||
`-hover-select`
|
||||
|
||||
@@ -591,7 +591,7 @@ Default: *dmenu*
|
||||
|
||||
Maximum number of lines the menu may show before scrolling.
|
||||
|
||||
rofi -lines 25
|
||||
rofi -dmenu -l 25
|
||||
|
||||
Default: *15*
|
||||
|
||||
@@ -645,7 +645,7 @@ Select first line that matches the given string
|
||||
`-mesg` *string*
|
||||
|
||||
Add a message line below the filter entry box. Supports Pango markup.
|
||||
For more information on supported markup, see [here](https://developer.gnome.org/pygtk/stable/pango-markup-language.html)
|
||||
For more information on supported markup, see [here](https://docs.gtk.org/Pango/pango_markup.html)
|
||||
|
||||
`-dump`
|
||||
|
||||
@@ -838,6 +838,36 @@ To get a searchable list of key bindings, run `rofi -show keys`.
|
||||
|
||||
A key binding starting with `!` will act when all keys have been released.
|
||||
|
||||
You can bind certain events to key-actions:
|
||||
|
||||
### Timeout
|
||||
|
||||
You can configure an action to be taken when rofi has not been interacted
|
||||
with for a certain amount of seconds. You can specify a keybinding to trigger
|
||||
after X seconds.
|
||||
|
||||
```css
|
||||
configuration {
|
||||
timeout {
|
||||
delay: 15;
|
||||
action: "kb-cancel";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Input change
|
||||
|
||||
When the input of the textbox changes:
|
||||
|
||||
```css
|
||||
configuration {
|
||||
inputchange {
|
||||
action: "kb-row-first";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Available Modi
|
||||
|
||||
### window
|
||||
|
@@ -41,6 +41,8 @@
|
||||
|
||||
extern Mode window_mode;
|
||||
extern Mode window_mode_cd;
|
||||
|
||||
void window_client_handle_signal(xcb_window_t win, gboolean create);
|
||||
#endif // WINDOW_MODE
|
||||
/** @}*/
|
||||
#endif // ROFI_DIALOG_WINDOW_H
|
||||
|
@@ -31,7 +31,7 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/** ABI version to check if loaded plugin is compatible. */
|
||||
#define ABI_VERSION 0x00000006
|
||||
#define ABI_VERSION 6u
|
||||
|
||||
/**
|
||||
* @param data Pointer to #Mode object.
|
||||
|
@@ -313,12 +313,13 @@ PangoAttrList *textbox_get_pango_attributes(textbox *tb);
|
||||
const char *textbox_get_visible_text(const textbox *tb);
|
||||
/**
|
||||
* @param wid The handle to the textbox.
|
||||
* @param height The height we want the desired width for
|
||||
*
|
||||
* TODO: is this deprecated by widget::get_desired_width
|
||||
*
|
||||
* @returns the desired width of the textbox.
|
||||
*/
|
||||
int textbox_get_desired_width(widget *wid);
|
||||
int textbox_get_desired_width(widget *wid, const int height);
|
||||
|
||||
/**
|
||||
* @param tb Handle to the textbox
|
||||
|
@@ -80,8 +80,8 @@ struct _widget {
|
||||
/** Handle mouse motion, used for dragging */
|
||||
gboolean (*motion_notify)(struct _widget *, gint x, gint y);
|
||||
|
||||
int (*get_desired_height)(struct _widget *);
|
||||
int (*get_desired_width)(struct _widget *);
|
||||
int (*get_desired_height)(struct _widget *, const int width);
|
||||
int (*get_desired_width)(struct _widget *, const int height);
|
||||
|
||||
void (*set_state)(struct _widget *, const char *);
|
||||
|
||||
|
@@ -316,21 +316,23 @@ gboolean widget_motion_notify(widget *wid, gint x, gint y);
|
||||
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
* @param width The Widget width to get height for
|
||||
*
|
||||
* Get the desired height of this widget recursively.
|
||||
*
|
||||
* @returns the desired height of the widget in pixels.
|
||||
*/
|
||||
int widget_get_desired_height(widget *wid);
|
||||
int widget_get_desired_height(widget *wid, const int width);
|
||||
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
* @param height The Widget height to get height for
|
||||
*
|
||||
* Get the desired width of this widget recursively.
|
||||
*
|
||||
* @returns the desired width of the widget in pixels.
|
||||
*/
|
||||
int widget_get_desired_width(widget *wid);
|
||||
int widget_get_desired_width(widget *wid, const int height);
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
*
|
||||
|
@@ -86,7 +86,6 @@ typedef struct _ParseObject {
|
||||
} ParseObject;
|
||||
|
||||
|
||||
GList *prev_imported_files = NULL;
|
||||
GQueue *file_queue = NULL;
|
||||
GQueue *queue = NULL;
|
||||
|
||||
@@ -177,6 +176,7 @@ UANYNP {ASCNP}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
|
||||
WHITESPACE [[:blank:]]
|
||||
WSO [[:blank:]]*
|
||||
WORD [[:alnum:]-]+
|
||||
WORD_ENV [[:alpha:]_][[:alnum:]_]*
|
||||
MEDIA_NAME [[:alpha:]-]+
|
||||
COLOR_NAME [[:alpha:]]+
|
||||
STRING \"{UANYN}*\"
|
||||
@@ -195,7 +195,7 @@ INHERIT (inherit)
|
||||
|
||||
ASTERIX \*
|
||||
|
||||
ENV $\{[[:alnum:]]*\}
|
||||
ENV $\{[[:alpha:]_][[:alnum:]_]*\}
|
||||
|
||||
MODIFIER_ADD \+
|
||||
MODIFIER_SUBTRACT -
|
||||
@@ -273,6 +273,7 @@ LIST_OPEN \[
|
||||
LIST_CLOSE \]
|
||||
|
||||
VAR_START "var"
|
||||
ENV_START "env"
|
||||
|
||||
CPP_COMMENT "//"
|
||||
C_COMMENT_OPEN "/*"
|
||||
@@ -290,6 +291,7 @@ CONFIGURATION (?i:configuration)
|
||||
%x PROPERTIES
|
||||
%x PROPERTIES_ENV
|
||||
%x PROPERTIES_VAR
|
||||
%x PROPERTIES_ENV_VAR
|
||||
%x PROPERTIES_VAR_DEFAULT
|
||||
%x PROPERTIES_LIST
|
||||
%x NAMESTR
|
||||
@@ -491,7 +493,7 @@ if ( queue == NULL ) {
|
||||
|
||||
/* After Namestr/Classstr we want to go to state str, then to { */
|
||||
<INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_ENV_VAR,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace
|
||||
|
||||
<SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; }
|
||||
<PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;}
|
||||
@@ -550,6 +552,26 @@ if ( queue == NULL ) {
|
||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES_ENV);
|
||||
}
|
||||
}
|
||||
<PROPERTIES_ENV_VAR>{WORD_ENV} {
|
||||
const char *val = g_getenv(yytext);
|
||||
if ( val ) {
|
||||
ParseObject *top = g_queue_peek_head ( file_queue );
|
||||
top->location = *yylloc;
|
||||
ParseObject *po = g_malloc0(sizeof(ParseObject));
|
||||
po->type = PT_ENV;
|
||||
po->input_str = val;
|
||||
po->str_len = strlen(val);
|
||||
current = po;
|
||||
g_queue_push_head ( file_queue, po );
|
||||
|
||||
yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
|
||||
yylloc->first_line = yylloc->last_line = 1;
|
||||
yylloc->first_column = yylloc->last_column = 1;
|
||||
yylloc->filename = current->filename;
|
||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES_ENV);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Color parsing. It is easier to do this at lexer level.
|
||||
@@ -610,17 +632,26 @@ if ( queue == NULL ) {
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{HSL} { return T_COL_HSL; }
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{HWB} { return T_COL_HWB; }
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CMYK} { return T_COL_CMYK; }
|
||||
/* Fluff */
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{VAR_START}{S_T_PARENT_LEFT} {
|
||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
||||
BEGIN(PROPERTIES_VAR);
|
||||
|
||||
<PROPERTIES_ENV_VAR,PROPERTIES_VAR>{S_T_PARENT_LEFT} {
|
||||
return T_PARENT_LEFT;
|
||||
}
|
||||
<PROPERTIES_VAR>{S_T_PARENT_RIGHT} {
|
||||
/* Fluff */
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{VAR_START} {
|
||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
||||
BEGIN(PROPERTIES_VAR);
|
||||
return T_VAR_START;
|
||||
}
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ENV_START} {
|
||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
||||
BEGIN(PROPERTIES_ENV_VAR);
|
||||
return T_ENV_START;
|
||||
}
|
||||
<PROPERTIES_VAR,PROPERTIES_ENV_VAR>{S_T_PARENT_RIGHT} {
|
||||
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
|
||||
return T_PARENT_RIGHT;
|
||||
}
|
||||
<PROPERTIES_VAR>{COMMA} {
|
||||
<PROPERTIES_VAR,PROPERTIES_ENV_VAR>{COMMA} {
|
||||
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
|
||||
BEGIN(PROPERTIES_VAR_DEFAULT);
|
||||
return T_COMMA;
|
||||
@@ -695,6 +726,7 @@ if ( queue == NULL ) {
|
||||
if ( po->type == PT_STRING_ALLOC ) {
|
||||
g_free( po->malloc_str);
|
||||
}
|
||||
g_free ( po->filename );
|
||||
g_free ( po );
|
||||
}
|
||||
po = g_queue_peek_head ( file_queue );
|
||||
@@ -794,7 +826,7 @@ if ( queue == NULL ) {
|
||||
return T_ELEMENT;
|
||||
}
|
||||
|
||||
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. {
|
||||
<PROPERTIES_ENV_VAR,PROPERTIES_VAR,PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. {
|
||||
yytext[yyleng-1] = '\0';
|
||||
return T_ERROR_PROPERTY;
|
||||
}
|
||||
@@ -843,6 +875,7 @@ gboolean rofi_theme_parse_file ( const char *file )
|
||||
if ( po->type == PT_STRING_ALLOC ) {
|
||||
g_free( po->malloc_str);
|
||||
}
|
||||
g_free ( po->filename );
|
||||
g_free ( po );
|
||||
}
|
||||
}
|
||||
@@ -879,6 +912,7 @@ gboolean rofi_theme_parse_string ( const char *string )
|
||||
if ( po->type == PT_STRING_ALLOC ) {
|
||||
g_free( po->malloc_str);
|
||||
}
|
||||
g_free ( po->filename );
|
||||
g_free ( po );
|
||||
}
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "theme.h"
|
||||
#include "xrmoptions.h"
|
||||
#include "css-colors.h"
|
||||
#include "rofi.h"
|
||||
|
||||
typedef struct YYLTYPE {
|
||||
int first_line;
|
||||
@@ -265,6 +266,10 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b )
|
||||
%token T_MEDIA_MAX "Max"
|
||||
%token T_MEDIA_SEP "-"
|
||||
|
||||
|
||||
%token T_VAR_START "var"
|
||||
%token T_ENV_START "env"
|
||||
|
||||
%type <theme> t_entry_list
|
||||
%type <theme> t_entry_list_included
|
||||
%type <list> t_entry_name_path
|
||||
@@ -318,6 +323,7 @@ t_main
|
||||
ThemeWidget *d = $2->widgets[i];
|
||||
rofi_theme_parse_merge_widgets(rofi_theme, d);
|
||||
}
|
||||
rofi_theme_free ( $2 );
|
||||
}
|
||||
;
|
||||
|
||||
@@ -372,7 +378,8 @@ t_entry_list:
|
||||
g_list_free ( $3 );
|
||||
}
|
||||
| t_entry_list T_PDEFAULTS T_BOPEN t_property_list_optional T_BCLOSE {
|
||||
rofi_theme_widget_add_properties ( $1, $4);
|
||||
ThemeWidget *widget = rofi_theme_find_or_create_name ( $1, "*" );
|
||||
rofi_theme_widget_add_properties (widget, $4);
|
||||
if ( $4 ) {
|
||||
g_hash_table_destroy ( $4 );
|
||||
}
|
||||
@@ -388,6 +395,7 @@ t_entry_list:
|
||||
ThemeWidget *d = $9->widgets[i];
|
||||
rofi_theme_parse_merge_widgets(widget, d);
|
||||
}
|
||||
g_free ( $4 );
|
||||
g_free ( name );
|
||||
}
|
||||
| t_entry_list T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_DOUBLE T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE {
|
||||
@@ -401,6 +409,7 @@ t_entry_list:
|
||||
ThemeWidget *d = $9->widgets[i];
|
||||
rofi_theme_parse_merge_widgets(widget, d);
|
||||
}
|
||||
g_free ( $4 );
|
||||
g_free ( name );
|
||||
}
|
||||
| t_entry_list T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_INT T_UNIT_PX T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE {
|
||||
@@ -414,6 +423,7 @@ t_entry_list:
|
||||
ThemeWidget *d = $10->widgets[i];
|
||||
rofi_theme_parse_merge_widgets(widget, d);
|
||||
}
|
||||
g_free ( $4 );
|
||||
g_free ( name );
|
||||
}
|
||||
;
|
||||
@@ -438,6 +448,9 @@ t_config_property
|
||||
yyerror ( &(@$), @$.filename, error );
|
||||
#else
|
||||
g_warning("%s:%d:%d: %s\n", @$.filename, @$.first_line, @$.first_column, error);
|
||||
GString *str = g_string_new("");
|
||||
g_string_append_printf(str,"%s:%d:%d: %s\n", @$.filename, @$.first_line, @$.first_column, error);
|
||||
rofi_add_error_message(str);
|
||||
#endif
|
||||
g_free(error);
|
||||
}
|
||||
@@ -481,17 +494,25 @@ t_property
|
||||
$$ = $3;
|
||||
$$->name = $1;
|
||||
}
|
||||
| t_property_name T_PSEP T_PARENT_LEFT T_ELEMENT T_PARENT_RIGHT T_PCLOSE{
|
||||
| t_property_name T_PSEP T_VAR_START T_PARENT_LEFT T_ELEMENT T_PARENT_RIGHT T_PCLOSE{
|
||||
$$ = rofi_theme_property_create ( P_LINK );
|
||||
$$->name = $1;
|
||||
$$->value.link.name = $4;
|
||||
$$->value.link.name = $5;
|
||||
}
|
||||
| t_property_name T_PSEP T_PARENT_LEFT T_ELEMENT T_COMMA t_property_element T_PARENT_RIGHT T_PCLOSE{
|
||||
| t_property_name T_PSEP T_VAR_START T_PARENT_LEFT T_ELEMENT T_COMMA t_property_element T_PARENT_RIGHT T_PCLOSE{
|
||||
$$ = rofi_theme_property_create ( P_LINK );
|
||||
$$->name = $1;
|
||||
$$->value.link.name = $4;
|
||||
$$->value.link.def_value = $6;
|
||||
$$->value.link.name = $5;
|
||||
$$->value.link.def_value = $7;
|
||||
}
|
||||
| t_property_name T_PSEP T_ENV_START T_PARENT_LEFT T_COMMA t_property_element T_PARENT_RIGHT T_PCLOSE {
|
||||
$$ = $6;
|
||||
$$->name = $1;
|
||||
}
|
||||
| t_property_name T_PSEP T_ENV_START T_PARENT_LEFT t_property_element T_COMMA t_property_element T_PARENT_RIGHT T_PCLOSE {
|
||||
$$ = $5;
|
||||
$$->name = $1;
|
||||
}
|
||||
|
||||
t_property_element
|
||||
: T_INHERIT {
|
||||
|
13
meson.build
13
meson.build
@@ -157,7 +157,7 @@ flex = generator(find_program('flex'),
|
||||
)
|
||||
bison = generator(find_program('bison'),
|
||||
output: [ '@BASENAME@.c', '@BASENAME@.h' ],
|
||||
arguments: [ '-d', '@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@' ]
|
||||
arguments: [ '--verbose', '-d', '@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@' ]
|
||||
)
|
||||
|
||||
rofi_sources = files(
|
||||
@@ -364,6 +364,7 @@ test('helper_pidfile test', executable('helper_pidfile.test', [
|
||||
objects: rofi.extract_objects([
|
||||
'config/config.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/helper.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/rofi-types.c',
|
||||
@@ -382,6 +383,7 @@ test('widget test', executable('widget.test', [
|
||||
'source/widgets/widget.c',
|
||||
'source/widgets/textbox.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/rofi-types.c',
|
||||
'source/css-colors.c',
|
||||
'source/helper.c',
|
||||
@@ -400,6 +402,7 @@ test('box test', executable('box.test', [
|
||||
'source/widgets/widget.c',
|
||||
'source/widgets/box.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/rofi-types.c',
|
||||
'source/css-colors.c',
|
||||
'config/config.c',
|
||||
@@ -417,6 +420,7 @@ test('scrollbar test', executable('scrollbar.test', [
|
||||
'source/widgets/widget.c',
|
||||
'source/widgets/scrollbar.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/rofi-types.c',
|
||||
'source/css-colors.c',
|
||||
'config/config.c',
|
||||
@@ -434,6 +438,7 @@ test('textbox test', executable('textbox.test', [
|
||||
'source/widgets/widget.c',
|
||||
'source/widgets/textbox.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/rofi-types.c',
|
||||
'source/css-colors.c',
|
||||
'source/helper.c',
|
||||
@@ -448,6 +453,7 @@ test('helper test', executable('helper.test', [
|
||||
objects: rofi.extract_objects([
|
||||
'config/config.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/helper.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/rofi-types.c',
|
||||
@@ -461,6 +467,7 @@ test('helper_expand test', executable('helper_expand.test', [
|
||||
objects: rofi.extract_objects([
|
||||
'config/config.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/helper.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/rofi-types.c',
|
||||
@@ -474,6 +481,7 @@ test('helper_config_cmdline_parser test', executable('helper_config_cmdline_pars
|
||||
objects: rofi.extract_objects([
|
||||
'config/config.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/helper.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/rofi-types.c',
|
||||
@@ -495,6 +503,7 @@ if check.found()
|
||||
'source/helper.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/rofi-types.c',
|
||||
'source/css-colors.c',
|
||||
]),
|
||||
@@ -509,6 +518,7 @@ if check.found()
|
||||
'source/dialogs/help-keys.c',
|
||||
'source/helper.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/mode.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/rofi-types.c',
|
||||
@@ -524,6 +534,7 @@ if check.found()
|
||||
'config/config.c',
|
||||
'source/helper.c',
|
||||
'source/theme.c',
|
||||
'source/css-colors.c',
|
||||
'source/xrmoptions.c',
|
||||
'source/rofi-types.c',
|
||||
]),
|
||||
|
@@ -201,7 +201,7 @@ converted to the new (internal) config system.
|
||||
This option allows you to set a fallback icon from applications.
|
||||
```css
|
||||
configuration {
|
||||
application_fallback_icon: "my-icon";
|
||||
application-fallback-icon: "my-icon";
|
||||
}
|
||||
```
|
||||
|
||||
|
@@ -121,6 +121,7 @@ static void read_add(DmenuModePrivateData *pd, char *data, gsize len) {
|
||||
pd->cmd_list[pd->cmd_list_length].icon_name = NULL;
|
||||
pd->cmd_list[pd->cmd_list_length].meta = NULL;
|
||||
pd->cmd_list[pd->cmd_list_length].info = NULL;
|
||||
pd->cmd_list[pd->cmd_list_length].nonselectable = FALSE;
|
||||
char *end = data;
|
||||
while (end < data + len && *end != '\0') {
|
||||
end++;
|
||||
@@ -544,7 +545,9 @@ static void dmenu_print_results(DmenuModePrivateData *pd, const char *input) {
|
||||
if (pd->selected_line != UINT32_MAX) {
|
||||
cmd = cmd_list[pd->selected_line].entry;
|
||||
}
|
||||
rofi_output_formatted_line(pd->format, cmd, pd->selected_line, input);
|
||||
if ( cmd ) {
|
||||
rofi_output_formatted_line(pd->format, cmd, pd->selected_line, input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1122,8 +1122,7 @@ static int drun_mode_init(Mode *sw) {
|
||||
drun_mode_parse_display_format();
|
||||
get_apps(pd);
|
||||
|
||||
pd->completer = create_new_file_browser();
|
||||
mode_init(pd->completer);
|
||||
pd->completer = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
static void drun_entry_clear(DRunModeEntry *e) {
|
||||
@@ -1235,6 +1234,8 @@ static ModeMode drun_mode_result(Mode *sw, int mretv, char **input,
|
||||
g_free(*input);
|
||||
*input = g_strdup(rmpd->old_completer_input);
|
||||
|
||||
rmpd->completer = create_new_file_browser();
|
||||
mode_init(rmpd->completer);
|
||||
rmpd->file_complete = TRUE;
|
||||
}
|
||||
g_regex_unref(regex);
|
||||
@@ -1257,7 +1258,10 @@ static void drun_mode_destroy(Mode *sw) {
|
||||
|
||||
g_free(rmpd->old_completer_input);
|
||||
g_free(rmpd->old_input);
|
||||
mode_destroy(rmpd->completer);
|
||||
if (rmpd->completer != NULL) {
|
||||
mode_destroy(rmpd->completer);
|
||||
g_free(rmpd->completer);
|
||||
}
|
||||
|
||||
g_strfreev(rmpd->current_desktop_list);
|
||||
g_strfreev(rmpd->show_categories);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -91,6 +92,7 @@ typedef struct {
|
||||
GFile *current_dir;
|
||||
FBFile *array;
|
||||
unsigned int array_length;
|
||||
unsigned int array_length_real;
|
||||
} FileBrowserModePrivateData;
|
||||
|
||||
/**
|
||||
@@ -118,6 +120,7 @@ static void free_list(FileBrowserModePrivateData *pd) {
|
||||
g_free(pd->array);
|
||||
pd->array = NULL;
|
||||
pd->array_length = 0;
|
||||
pd->array_length_real = 0;
|
||||
}
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
@@ -172,7 +175,7 @@ static gint compare(gconstpointer a, gconstpointer b, gpointer data) {
|
||||
return comparator(a, b, data);
|
||||
}
|
||||
|
||||
static time_t get_time(const struct stat *statbuf) {
|
||||
static time_t get_time(const GStatBuf *statbuf) {
|
||||
switch (file_browser_config.sorting_time) {
|
||||
case FB_MTIME:
|
||||
return statbuf->st_mtim.tv_sec;
|
||||
@@ -186,17 +189,30 @@ static time_t get_time(const struct stat *statbuf) {
|
||||
}
|
||||
|
||||
static void set_time(FBFile *file) {
|
||||
gchar *path = g_filename_from_utf8(file->path, -1, NULL, NULL, NULL);
|
||||
// GError *error = NULL;
|
||||
// gchar *path = g_filename_from_utf8(file->path, -1, NULL, NULL, &error);
|
||||
// if (error) {
|
||||
// g_warning("Failed to convert filename: %s: %s", file->path,
|
||||
// error->message); g_error_free(error); return;
|
||||
// }
|
||||
|
||||
struct stat statbuf;
|
||||
GStatBuf statbuf;
|
||||
|
||||
if (stat(path, &statbuf) == 0) {
|
||||
if (g_lstat(file->path, &statbuf) == 0) {
|
||||
file->time = get_time(&statbuf);
|
||||
} else {
|
||||
g_warning("Failed to stat file: %s, %s", path, strerror(errno));
|
||||
g_warning("Failed to stat file: %s, %s", file->path, strerror(errno));
|
||||
}
|
||||
|
||||
g_free(path);
|
||||
// g_free(path);
|
||||
}
|
||||
|
||||
inline static void fb_resize_array(FileBrowserModePrivateData *pd) {
|
||||
if ((pd->array_length + 1) > pd->array_length_real) {
|
||||
pd->array_length_real += 256;
|
||||
pd->array =
|
||||
g_realloc(pd->array, (pd->array_length_real + 1) * sizeof(FBFile));
|
||||
}
|
||||
}
|
||||
|
||||
static void get_file_browser(Mode *sw) {
|
||||
@@ -212,8 +228,7 @@ static void get_file_browser(Mode *sw) {
|
||||
struct dirent *rd = NULL;
|
||||
while ((rd = readdir(dir)) != NULL) {
|
||||
if (g_strcmp0(rd->d_name, "..") == 0) {
|
||||
pd->array =
|
||||
g_realloc(pd->array, (pd->array_length + 1) * sizeof(FBFile));
|
||||
fb_resize_array(pd);
|
||||
// Rofi expects utf-8, so lets convert the filename.
|
||||
pd->array[pd->array_length].name = g_strdup("..");
|
||||
pd->array[pd->array_length].path = NULL;
|
||||
@@ -238,11 +253,13 @@ static void get_file_browser(Mode *sw) {
|
||||
break;
|
||||
case DT_REG:
|
||||
case DT_DIR:
|
||||
pd->array =
|
||||
g_realloc(pd->array, (pd->array_length + 1) * sizeof(FBFile));
|
||||
fb_resize_array(pd);
|
||||
// Rofi expects utf-8, so lets convert the filename.
|
||||
pd->array[pd->array_length].name =
|
||||
g_filename_to_utf8(rd->d_name, -1, NULL, NULL, NULL);
|
||||
if (pd->array[pd->array_length].name == NULL) {
|
||||
pd->array[pd->array_length].name = rofi_force_utf8(rd->d_name, -1);
|
||||
}
|
||||
pd->array[pd->array_length].path =
|
||||
g_build_filename(cdir, rd->d_name, NULL);
|
||||
pd->array[pd->array_length].type =
|
||||
@@ -257,11 +274,13 @@ static void get_file_browser(Mode *sw) {
|
||||
pd->array_length++;
|
||||
break;
|
||||
case DT_LNK:
|
||||
pd->array =
|
||||
g_realloc(pd->array, (pd->array_length + 1) * sizeof(FBFile));
|
||||
fb_resize_array(pd);
|
||||
// Rofi expects utf-8, so lets convert the filename.
|
||||
pd->array[pd->array_length].name =
|
||||
g_filename_to_utf8(rd->d_name, -1, NULL, NULL, NULL);
|
||||
if (pd->array[pd->array_length].name == NULL) {
|
||||
pd->array[pd->array_length].name = rofi_force_utf8(rd->d_name, -1);
|
||||
}
|
||||
pd->array[pd->array_length].path =
|
||||
g_build_filename(cdir, rd->d_name, NULL);
|
||||
pd->array[pd->array_length].icon_fetch_uid = 0;
|
||||
@@ -273,11 +292,13 @@ static void get_file_browser(Mode *sw) {
|
||||
// mark it as file.
|
||||
// TODO have a 'broken link' mode?
|
||||
// Convert full path to right encoding.
|
||||
char *file = g_filename_from_utf8(pd->array[pd->array_length].path,
|
||||
-1, NULL, NULL, NULL);
|
||||
if (file) {
|
||||
struct stat statbuf;
|
||||
if (stat(file, &statbuf) == 0) {
|
||||
// DD: Path should be in file encoding, not utf-8
|
||||
// char *file =
|
||||
// g_filename_from_utf8(pd->array[pd->array_length].path,
|
||||
// -1, NULL, NULL, NULL);
|
||||
if (pd->array[pd->array_length].path) {
|
||||
GStatBuf statbuf;
|
||||
if (g_stat(pd->array[pd->array_length].path, &statbuf) == 0) {
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
pd->array[pd->array_length].type = DIRECTORY;
|
||||
} else if (S_ISREG(statbuf.st_mode)) {
|
||||
@@ -288,10 +309,11 @@ static void get_file_browser(Mode *sw) {
|
||||
pd->array[pd->array_length].time = get_time(&statbuf);
|
||||
}
|
||||
} else {
|
||||
g_warning("Failed to stat file: %s, %s", file, strerror(errno));
|
||||
g_warning("Failed to stat file: %s, %s",
|
||||
pd->array[pd->array_length].path, strerror(errno));
|
||||
}
|
||||
|
||||
g_free(file);
|
||||
// g_free(file);
|
||||
}
|
||||
}
|
||||
pd->array_length++;
|
||||
@@ -300,6 +322,7 @@ static void get_file_browser(Mode *sw) {
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
g_free(cdir);
|
||||
g_qsort_with_data(pd->array, pd->array_length, sizeof(FBFile), compare, NULL);
|
||||
}
|
||||
|
||||
@@ -434,12 +457,12 @@ static ModeMode file_browser_mode_result(Mode *sw, int mretv, char **input,
|
||||
get_file_browser(sw);
|
||||
return RESET_DIALOG;
|
||||
} else if (pd->array[selected_line].type == RFILE) {
|
||||
char *d = g_filename_from_utf8(pd->array[selected_line].path, -1, NULL,
|
||||
NULL, NULL);
|
||||
char *d_esc = g_shell_quote(d);
|
||||
// char *d = g_filename_from_utf8(pd->array[selected_line].path,
|
||||
// -1, NULL,
|
||||
// NULL, NULL);
|
||||
char *d_esc = g_shell_quote(pd->array[selected_line].path);
|
||||
char *cmd = g_strdup_printf("xdg-open %s", d_esc);
|
||||
g_free(d_esc);
|
||||
g_free(d);
|
||||
char *cdir = g_file_get_path(pd->current_dir);
|
||||
helper_execute_command(cdir, cmd, FALSE, NULL);
|
||||
g_free(cdir);
|
||||
|
@@ -382,8 +382,7 @@ static int run_mode_init(Mode *sw) {
|
||||
RunModePrivateData *pd = g_malloc0(sizeof(*pd));
|
||||
sw->private_data = (void *)pd;
|
||||
pd->cmd_list = get_apps(&(pd->cmd_list_length));
|
||||
pd->completer = create_new_file_browser();
|
||||
mode_init(pd->completer);
|
||||
pd->completer = NULL;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -400,7 +399,10 @@ static void run_mode_destroy(Mode *sw) {
|
||||
g_free(rmpd->cmd_list);
|
||||
g_free(rmpd->old_input);
|
||||
g_free(rmpd->old_completer_input);
|
||||
mode_destroy(rmpd->completer);
|
||||
if (rmpd->completer != NULL) {
|
||||
mode_destroy(rmpd->completer);
|
||||
g_free(rmpd->completer);
|
||||
}
|
||||
g_free(rmpd);
|
||||
sw->private_data = NULL;
|
||||
}
|
||||
@@ -484,6 +486,8 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input,
|
||||
g_free(*input);
|
||||
*input = g_strdup(rmpd->old_completer_input);
|
||||
|
||||
rmpd->completer = create_new_file_browser();
|
||||
mode_init(rmpd->completer);
|
||||
rmpd->file_complete = TRUE;
|
||||
}
|
||||
}
|
||||
|
@@ -147,7 +147,7 @@ typedef struct {
|
||||
unsigned int title_len;
|
||||
unsigned int role_len;
|
||||
GRegex *window_regex;
|
||||
} ModeModePrivateData;
|
||||
} WindowModePrivateData;
|
||||
|
||||
winlist *cache_client = NULL;
|
||||
|
||||
@@ -236,6 +236,9 @@ static void winlist_free(winlist *l) {
|
||||
* @returns -1 if failed, index is successful.
|
||||
*/
|
||||
static int winlist_find(winlist *l, xcb_window_t w) {
|
||||
if (l == NULL) {
|
||||
return -1;
|
||||
}
|
||||
// iterate backwards. Theory is: windows most often accessed will be
|
||||
// nearer the end. Testing with kcachegrind seems to support this...
|
||||
int i;
|
||||
@@ -305,7 +308,7 @@ static int client_has_window_type(client *c, xcb_atom_t type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static client *window_client(ModeModePrivateData *pd, xcb_window_t win) {
|
||||
static client *window_client(WindowModePrivateData *pd, xcb_window_t win) {
|
||||
if (win == XCB_WINDOW_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -378,9 +381,35 @@ static client *window_client(ModeModePrivateData *pd, xcb_window_t win) {
|
||||
g_free(attr);
|
||||
return c;
|
||||
}
|
||||
|
||||
guint window_reload_timeout = 0;
|
||||
static gboolean window_client_reload(G_GNUC_UNUSED void *data) {
|
||||
window_reload_timeout = 0;
|
||||
if (window_mode.private_data) {
|
||||
window_mode._destroy(&window_mode);
|
||||
window_mode._init(&window_mode);
|
||||
}
|
||||
if (window_mode_cd.private_data) {
|
||||
window_mode._destroy(&window_mode_cd);
|
||||
window_mode._init(&window_mode_cd);
|
||||
}
|
||||
if (window_mode.private_data || window_mode_cd.private_data) {
|
||||
rofi_view_reload();
|
||||
}
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
void window_client_handle_signal(xcb_window_t win, gboolean create) {
|
||||
// g_idle_add_full(G_PRIORITY_HIGH_IDLE, window_client_reload, NULL, NULL);
|
||||
if (window_reload_timeout > 0) {
|
||||
g_source_remove(window_reload_timeout);
|
||||
window_reload_timeout = 0;
|
||||
}
|
||||
window_reload_timeout = g_timeout_add(100, window_client_reload, NULL);
|
||||
}
|
||||
static int window_match(const Mode *sw, rofi_int_matcher **tokens,
|
||||
unsigned int index) {
|
||||
ModeModePrivateData *rmpd = (ModeModePrivateData *)mode_get_private_data(sw);
|
||||
WindowModePrivateData *rmpd =
|
||||
(WindowModePrivateData *)mode_get_private_data(sw);
|
||||
int match = 1;
|
||||
const winlist *ids = (winlist *)rmpd->ids;
|
||||
// Want to pull directly out of cache, X calls are not thread safe.
|
||||
@@ -466,8 +495,8 @@ static void window_mode_parse_fields() {
|
||||
}
|
||||
|
||||
static unsigned int window_mode_get_num_entries(const Mode *sw) {
|
||||
const ModeModePrivateData *pd =
|
||||
(const ModeModePrivateData *)mode_get_private_data(sw);
|
||||
const WindowModePrivateData *pd =
|
||||
(const WindowModePrivateData *)mode_get_private_data(sw);
|
||||
|
||||
return pd->ids ? pd->ids->len : 0;
|
||||
}
|
||||
@@ -492,7 +521,8 @@ static const char *_window_name_list_entry(const char *str, uint32_t length,
|
||||
return &str[offset];
|
||||
}
|
||||
static void _window_mode_load_data(Mode *sw, unsigned int cd) {
|
||||
ModeModePrivateData *pd = (ModeModePrivateData *)mode_get_private_data(sw);
|
||||
WindowModePrivateData *pd =
|
||||
(WindowModePrivateData *)mode_get_private_data(sw);
|
||||
// find window list
|
||||
xcb_window_t curr_win_id;
|
||||
int found = 0;
|
||||
@@ -603,27 +633,31 @@ static void _window_mode_load_data(Mode *sw, unsigned int cd) {
|
||||
g_free(output);
|
||||
} else {
|
||||
winclient->wmdesktopstr = g_strdup("Invalid name");
|
||||
pd->wmdn_len = MAX(pd->wmdn_len,
|
||||
g_utf8_strlen(winclient->wmdesktopstr, -1));
|
||||
winclient->wmdesktopstr_len =
|
||||
g_utf8_strlen(winclient->wmdesktopstr, -1);
|
||||
pd->wmdn_len = MAX(pd->wmdn_len, winclient->wmdesktopstr_len);
|
||||
}
|
||||
} else {
|
||||
winclient->wmdesktopstr = g_markup_escape_text(
|
||||
_window_name_list_entry(names.strings, names.strings_len,
|
||||
winclient->wmdesktop),
|
||||
-1);
|
||||
pd->wmdn_len =
|
||||
MAX(pd->wmdn_len, g_utf8_strlen(winclient->wmdesktopstr, -1));
|
||||
winclient->wmdesktopstr_len =
|
||||
g_utf8_strlen(winclient->wmdesktopstr, -1);
|
||||
pd->wmdn_len = MAX(pd->wmdn_len, winclient->wmdesktopstr_len);
|
||||
}
|
||||
} else {
|
||||
winclient->wmdesktopstr =
|
||||
g_strdup_printf("%u", (uint32_t)winclient->wmdesktop);
|
||||
pd->wmdn_len =
|
||||
MAX(pd->wmdn_len, g_utf8_strlen(winclient->wmdesktopstr, -1));
|
||||
winclient->wmdesktopstr_len =
|
||||
g_utf8_strlen(winclient->wmdesktopstr, -1);
|
||||
pd->wmdn_len = MAX(pd->wmdn_len, winclient->wmdesktopstr_len);
|
||||
}
|
||||
} else {
|
||||
winclient->wmdesktopstr = g_strdup("");
|
||||
pd->wmdn_len =
|
||||
MAX(pd->wmdn_len, g_utf8_strlen(winclient->wmdesktopstr, -1));
|
||||
winclient->wmdesktopstr_len =
|
||||
g_utf8_strlen(winclient->wmdesktopstr, -1);
|
||||
pd->wmdn_len = MAX(pd->wmdn_len, winclient->wmdesktopstr_len);
|
||||
}
|
||||
if (cd && winclient->wmdesktop != current_desktop) {
|
||||
continue;
|
||||
@@ -640,7 +674,7 @@ static void _window_mode_load_data(Mode *sw, unsigned int cd) {
|
||||
}
|
||||
static int window_mode_init(Mode *sw) {
|
||||
if (mode_get_private_data(sw) == NULL) {
|
||||
ModeModePrivateData *pd = g_malloc0(sizeof(*pd));
|
||||
WindowModePrivateData *pd = g_malloc0(sizeof(*pd));
|
||||
pd->window_regex = g_regex_new("{[-\\w]+(:-?[0-9]+)?}", 0, 0, NULL);
|
||||
mode_set_private_data(sw, (void *)pd);
|
||||
_window_mode_load_data(sw, FALSE);
|
||||
@@ -652,7 +686,7 @@ static int window_mode_init(Mode *sw) {
|
||||
}
|
||||
static int window_mode_init_cd(Mode *sw) {
|
||||
if (mode_get_private_data(sw) == NULL) {
|
||||
ModeModePrivateData *pd = g_malloc0(sizeof(*pd));
|
||||
WindowModePrivateData *pd = g_malloc0(sizeof(*pd));
|
||||
pd->window_regex = g_regex_new("{[-\\w]+(:-?[0-9]+)?}", 0, 0, NULL);
|
||||
mode_set_private_data(sw, (void *)pd);
|
||||
_window_mode_load_data(sw, TRUE);
|
||||
@@ -696,7 +730,8 @@ static inline int act_on_window(xcb_window_t window) {
|
||||
static ModeMode window_mode_result(Mode *sw, int mretv,
|
||||
G_GNUC_UNUSED char **input,
|
||||
unsigned int selected_line) {
|
||||
ModeModePrivateData *rmpd = (ModeModePrivateData *)mode_get_private_data(sw);
|
||||
WindowModePrivateData *rmpd =
|
||||
(WindowModePrivateData *)mode_get_private_data(sw);
|
||||
ModeMode retv = MODE_EXIT;
|
||||
if ((mretv & (MENU_OK))) {
|
||||
if (mretv & MENU_CUSTOM_ACTION) {
|
||||
@@ -754,18 +789,8 @@ static ModeMode window_mode_result(Mode *sw, int mretv,
|
||||
Property *p =
|
||||
rofi_theme_find_property(wid, P_BOOLEAN, "close-on-delete", TRUE);
|
||||
if (p && p->type == P_BOOLEAN && p->value.b == FALSE) {
|
||||
// Force a reload.
|
||||
client_free(rmpd->ids->data[selected_line]);
|
||||
g_free(rmpd->ids->data[selected_line]);
|
||||
memmove(&(rmpd->ids->array[selected_line]),
|
||||
&(rmpd->ids->array[selected_line + 1]),
|
||||
rmpd->ids->len - selected_line);
|
||||
memmove(&(rmpd->ids->data[selected_line]),
|
||||
&(rmpd->ids->data[selected_line + 1]),
|
||||
rmpd->ids->len - selected_line);
|
||||
rmpd->ids->len--;
|
||||
|
||||
retv = RELOAD_DIALOG;
|
||||
return RELOAD_DIALOG;
|
||||
}
|
||||
} else if ((mretv & MENU_CUSTOM_INPUT) && *input != NULL &&
|
||||
*input[0] != '\0') {
|
||||
@@ -793,7 +818,8 @@ static ModeMode window_mode_result(Mode *sw, int mretv,
|
||||
}
|
||||
|
||||
static void window_mode_destroy(Mode *sw) {
|
||||
ModeModePrivateData *rmpd = (ModeModePrivateData *)mode_get_private_data(sw);
|
||||
WindowModePrivateData *rmpd =
|
||||
(WindowModePrivateData *)mode_get_private_data(sw);
|
||||
if (rmpd != NULL) {
|
||||
winlist_free(rmpd->ids);
|
||||
x11_cache_free();
|
||||
@@ -804,7 +830,7 @@ static void window_mode_destroy(Mode *sw) {
|
||||
}
|
||||
}
|
||||
struct arg {
|
||||
const ModeModePrivateData *pd;
|
||||
const WindowModePrivateData *pd;
|
||||
client *c;
|
||||
};
|
||||
|
||||
@@ -869,7 +895,7 @@ static gboolean helper_eval_cb(const GMatchInfo *info, GString *str,
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
static char *_generate_display_string(const ModeModePrivateData *pd,
|
||||
static char *_generate_display_string(const WindowModePrivateData *pd,
|
||||
client *c) {
|
||||
struct arg d = {pd, c};
|
||||
char *res = g_regex_replace_eval(pd->window_regex, config.window_format, -1,
|
||||
@@ -880,10 +906,10 @@ static char *_generate_display_string(const ModeModePrivateData *pd,
|
||||
static char *_get_display_value(const Mode *sw, unsigned int selected_line,
|
||||
int *state, G_GNUC_UNUSED GList **list,
|
||||
int get_entry) {
|
||||
ModeModePrivateData *rmpd = mode_get_private_data(sw);
|
||||
WindowModePrivateData *rmpd = mode_get_private_data(sw);
|
||||
client *c = window_client(rmpd, rmpd->ids->array[selected_line]);
|
||||
if (c == NULL) {
|
||||
return get_entry ? g_strdup("Window has fanished") : NULL;
|
||||
return get_entry ? g_strdup("Window has vanished") : NULL;
|
||||
}
|
||||
if (c->demands) {
|
||||
*state |= URGENT;
|
||||
@@ -997,8 +1023,11 @@ static cairo_surface_t *get_net_wm_icon(xcb_window_t xid,
|
||||
}
|
||||
static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line,
|
||||
int size) {
|
||||
ModeModePrivateData *rmpd = mode_get_private_data(sw);
|
||||
WindowModePrivateData *rmpd = mode_get_private_data(sw);
|
||||
client *c = window_client(rmpd, rmpd->ids->array[selected_line]);
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (config.window_thumbnail && c->thumbnail_checked == FALSE) {
|
||||
c->icon = x11_helper_get_screenshot_surface_window(c->window, size);
|
||||
c->thumbnail_checked = TRUE;
|
||||
@@ -1011,7 +1040,9 @@ static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line,
|
||||
if (c->icon_fetch_uid > 0) {
|
||||
return rofi_icon_fetcher_get(c->icon_fetch_uid);
|
||||
}
|
||||
c->icon_fetch_uid = rofi_icon_fetcher_query(c->class, size);
|
||||
char *class_lower = g_utf8_strdown(c->class, -1);
|
||||
c->icon_fetch_uid = rofi_icon_fetcher_query(class_lower, size);
|
||||
g_free(class_lower);
|
||||
return rofi_icon_fetcher_get(c->icon_fetch_uid);
|
||||
}
|
||||
return c->icon;
|
||||
|
@@ -182,7 +182,8 @@ static char *utf8_helper_simplify_string(const char *s) {
|
||||
0,
|
||||
};
|
||||
// Compose the string in maximally composed form.
|
||||
char *str = g_malloc0((g_utf8_strlen(s, 0) * 6 + 2));
|
||||
ssize_t str_size = (g_utf8_strlen(s, -1) * 6 + 2 + 1) * sizeof(char);
|
||||
char *str = g_malloc0(str_size);
|
||||
char *striter = str;
|
||||
for (const char *iter = s; iter && *iter; iter = g_utf8_next_char(iter)) {
|
||||
gunichar uc = g_utf8_get_char(iter);
|
||||
|
@@ -445,7 +445,7 @@ static void help_print_no_arguments(void) {
|
||||
/**
|
||||
* Cleanup globally allocated memory.
|
||||
*/
|
||||
static void cleanup() {
|
||||
static void cleanup(void) {
|
||||
for (unsigned int i = 0; i < num_modi; i++) {
|
||||
mode_destroy(modi[i]);
|
||||
}
|
||||
@@ -668,7 +668,7 @@ static gboolean main_loop_signal_handler_int(G_GNUC_UNUSED gpointer data) {
|
||||
g_main_loop_quit(main_loop);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
static void show_error_dialog() {
|
||||
static void show_error_dialog(void) {
|
||||
GString *emesg =
|
||||
g_string_new("The following errors were detected when starting rofi:\n");
|
||||
GList *iter = g_list_first(list_of_error_msgs);
|
||||
@@ -680,7 +680,7 @@ static void show_error_dialog() {
|
||||
index++;
|
||||
}
|
||||
if (g_list_length(iter) > 1) {
|
||||
g_string_append_printf(emesg, "\nThere are <b>%d</b> more errors.",
|
||||
g_string_append_printf(emesg, "\nThere are <b>%u</b> more errors.",
|
||||
g_list_length(iter) - 1);
|
||||
}
|
||||
rofi_view_error_dialog(emesg->str, ERROR_MSG_MARKUP);
|
||||
@@ -800,7 +800,7 @@ int main(int argc, char *argv[]) {
|
||||
{
|
||||
const char *ro_pid = g_getenv("ROFI_OUTSIDE");
|
||||
if (ro_pid != NULL) {
|
||||
int ro_pidi = g_ascii_strtoll(ro_pid, NULL, 0);
|
||||
pid_t ro_pidi = (pid_t)g_ascii_strtoll(ro_pid, NULL, 0);
|
||||
if (kill(ro_pidi, 0) == 0) {
|
||||
printf("Do not launch rofi from inside rofi.\r\n");
|
||||
return EXIT_FAILURE;
|
||||
@@ -914,7 +914,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
TICK_N("Setup mainloop");
|
||||
|
||||
bindings = nk_bindings_new(0);
|
||||
bindings = nk_bindings_new(0lu);
|
||||
TICK_N("NK Bindings");
|
||||
|
||||
if (!display_setup(main_loop, bindings)) {
|
||||
@@ -1031,6 +1031,12 @@ int main(int argc, char *argv[]) {
|
||||
cleanup();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (find_arg("-dump-processed-theme") >= 0) {
|
||||
rofi_theme_parse_process_conditionals();
|
||||
rofi_theme_print(rofi_theme);
|
||||
cleanup();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
if (find_arg("-dump-config") >= 0) {
|
||||
config_parse_dump_config_rasi_format(stdout, FALSE);
|
||||
cleanup();
|
||||
@@ -1047,7 +1053,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
unsigned int interval = 1;
|
||||
if (find_arg_uint("-record-screenshots", &interval)) {
|
||||
g_timeout_add(1000 / (double)interval, record, NULL);
|
||||
g_timeout_add((guint)(1000 / (double)interval), record, NULL);
|
||||
}
|
||||
if (find_arg("-benchmark-ui") >= 0) {
|
||||
config.benchmark_ui = TRUE;
|
||||
|
133
source/theme.c
133
source/theme.c
@@ -187,6 +187,9 @@ void rofi_theme_property_free(Property *p) {
|
||||
g_free(p->name);
|
||||
if (p->type == P_STRING) {
|
||||
g_free(p->value.s);
|
||||
} else if (p->type == P_LIST) {
|
||||
g_list_free_full(p->value.list, g_free);
|
||||
p->value.list = 0;
|
||||
} else if (p->type == P_LINK) {
|
||||
g_free(p->value.link.name);
|
||||
if (p->value.link.def_value) {
|
||||
@@ -291,6 +294,27 @@ static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rofi_theme_print_color(ThemeColor color) {
|
||||
uint8_t r, g, b;
|
||||
g = 255 * color.green;
|
||||
r = 255 * color.red;
|
||||
b = 255 * color.blue;
|
||||
if (color.alpha < 0.00001) {
|
||||
printf("transparent");
|
||||
return;
|
||||
}
|
||||
for (uint32_t x = 0; x < num_CSSColors; x++) {
|
||||
if (CSSColors[x].r == r && CSSColors[x].g == g && CSSColors[x].b == b) {
|
||||
printf("%s", CSSColors[x].name);
|
||||
if (color.alpha < 1) {
|
||||
printf("/%.0f%%", color.alpha * 100.0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )", (color.red * 255.0),
|
||||
(color.green * 255.0), (color.blue * 255.0), (color.alpha * 100.0));
|
||||
}
|
||||
static void rofi_theme_print_distance(RofiDistance d) {
|
||||
if (d.base.modtype == ROFI_DISTANCE_MODIFIER_GROUP) {
|
||||
fputs("calc( ", stdout);
|
||||
@@ -343,11 +367,7 @@ static void int_rofi_theme_print_property(Property *p) {
|
||||
printf("italic ");
|
||||
}
|
||||
if (p->value.highlight.style & ROFI_HL_COLOR) {
|
||||
printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )",
|
||||
(p->value.highlight.color.red * 255.0),
|
||||
(p->value.highlight.color.green * 255.0),
|
||||
(p->value.highlight.color.blue * 255.0),
|
||||
(p->value.highlight.color.alpha * 100.0));
|
||||
rofi_theme_print_color(p->value.highlight.color);
|
||||
}
|
||||
break;
|
||||
case P_POSITION: {
|
||||
@@ -399,9 +419,7 @@ static void int_rofi_theme_print_property(Property *p) {
|
||||
printf("%s", p->value.b ? "true" : "false");
|
||||
break;
|
||||
case P_COLOR:
|
||||
printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )", (p->value.color.red * 255.0),
|
||||
(p->value.color.green * 255.0), (p->value.color.blue * 255.0),
|
||||
(p->value.color.alpha * 100.0));
|
||||
rofi_theme_print_color(p->value.color);
|
||||
break;
|
||||
case P_IMAGE: {
|
||||
if (p->value.image.type == ROFI_IMAGE_URL) {
|
||||
@@ -413,9 +431,7 @@ static void int_rofi_theme_print_property(Property *p) {
|
||||
for (GList *l = g_list_first(p->value.image.colors); l != NULL;
|
||||
l = g_list_next(l)) {
|
||||
ThemeColor *color = (ThemeColor *)l->data;
|
||||
printf("rgba ( %.0f, %.0f, %.0f, %.0f %% )", (color->red * 255.0),
|
||||
(color->green * 255.0), (color->blue * 255.0),
|
||||
(color->alpha * 100.0));
|
||||
rofi_theme_print_color(*color);
|
||||
index++;
|
||||
if (index < length) {
|
||||
printf(", ");
|
||||
@@ -756,7 +772,8 @@ static int rofi_theme_get_position_inside(Property *p, const widget *widget,
|
||||
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
|
||||
Property *pv =
|
||||
rofi_theme_find_property(parent, P_POSITION, property, FALSE);
|
||||
return rofi_theme_get_position_inside(pv, widget->parent, property, def);
|
||||
return rofi_theme_get_position_inside(pv, widget->parent, property,
|
||||
def);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
@@ -795,7 +812,7 @@ int rofi_theme_get_integer(const widget *widget, const char *property,
|
||||
int def) {
|
||||
ThemeWidget *wid = rofi_theme_find_widget(widget->name, widget->state, FALSE);
|
||||
Property *p = rofi_theme_find_property(wid, P_INTEGER, property, FALSE);
|
||||
return rofi_theme_get_integer_inside(p, widget, property, def);
|
||||
return (int)rofi_theme_get_integer_inside(p, widget, property, (double)def);
|
||||
}
|
||||
static RofiDistance rofi_theme_get_distance_inside(Property *p,
|
||||
const widget *widget,
|
||||
@@ -872,7 +889,8 @@ static RofiOrientation rofi_theme_get_orientation_inside(Property *p,
|
||||
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
|
||||
Property *pv =
|
||||
rofi_theme_find_property(parent, P_ORIENTATION, property, FALSE);
|
||||
return rofi_theme_get_orientation_inside(pv, widget->parent, property, def);
|
||||
return rofi_theme_get_orientation_inside(pv, widget->parent, property,
|
||||
def);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
@@ -901,7 +919,8 @@ static RofiCursorType rofi_theme_get_cursor_type_inside(Property *p,
|
||||
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
|
||||
Property *pv =
|
||||
rofi_theme_find_property(parent, P_CURSOR, property, FALSE);
|
||||
return rofi_theme_get_cursor_type_inside(pv, widget->parent, property, def);
|
||||
return rofi_theme_get_cursor_type_inside(pv, widget->parent, property,
|
||||
def);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
@@ -945,6 +964,29 @@ const char *rofi_theme_get_string(const widget *widget, const char *property,
|
||||
Property *p = rofi_theme_find_property(wid, P_STRING, property, FALSE);
|
||||
return rofi_theme_get_string_inside(p, widget, property, def);
|
||||
}
|
||||
|
||||
static double rofi_theme_get_double_integer_fb_inside(Property *p,
|
||||
const widget *widget,
|
||||
const char *property,
|
||||
double def) {
|
||||
if (p) {
|
||||
if (p->type == P_INHERIT) {
|
||||
if (widget->parent) {
|
||||
ThemeWidget *parent =
|
||||
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
|
||||
Property *pv =
|
||||
rofi_theme_find_property(parent, P_INTEGER, property, FALSE);
|
||||
return rofi_theme_get_double_integer_fb_inside(pv, widget->parent,
|
||||
property, def);
|
||||
}
|
||||
return def;
|
||||
}
|
||||
return p->value.i;
|
||||
}
|
||||
g_debug("Theme entry: #%s %s property %s unset.", widget->name,
|
||||
widget->state ? widget->state : "", property);
|
||||
return def;
|
||||
}
|
||||
static double rofi_theme_get_double_inside(const widget *orig, Property *p,
|
||||
const widget *widget,
|
||||
const char *property, double def) {
|
||||
@@ -961,11 +1003,10 @@ static double rofi_theme_get_double_inside(const widget *orig, Property *p,
|
||||
}
|
||||
return p->value.f;
|
||||
}
|
||||
ThemeWidget *wid =
|
||||
rofi_theme_find_widget(orig->name, widget->state, FALSE);
|
||||
ThemeWidget *wid = rofi_theme_find_widget(orig->name, widget->state, FALSE);
|
||||
// Fallback to integer if double is not found.
|
||||
p = rofi_theme_find_property(wid, P_INTEGER, property, FALSE);
|
||||
return rofi_theme_get_integer_inside(p, widget, property, def);
|
||||
return rofi_theme_get_double_integer_fb_inside(p, widget, property, def);
|
||||
}
|
||||
double rofi_theme_get_double(const widget *widget, const char *property,
|
||||
double def) {
|
||||
@@ -1157,7 +1198,8 @@ static GList *rofi_theme_get_list_inside(Property *p, const widget *widget,
|
||||
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
|
||||
Property *pv =
|
||||
rofi_theme_find_property(parent, P_LIST, property, FALSE);
|
||||
return rofi_theme_get_list_inside(pv, widget->parent, property, defaults);
|
||||
return rofi_theme_get_list_inside(pv, widget->parent, property,
|
||||
defaults);
|
||||
}
|
||||
} else if (p->type == P_LIST) {
|
||||
return g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL);
|
||||
@@ -1321,22 +1363,6 @@ char *rofi_theme_parse_prepare_file(const char *file, const char *parent_file) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
static void rofi_theme_parse_merge_widgets_no_media(ThemeWidget *parent,
|
||||
ThemeWidget *child) {
|
||||
g_assert(parent != NULL);
|
||||
g_assert(child != NULL);
|
||||
|
||||
if (parent == rofi_theme && g_strcmp0(child->name, "*") == 0) {
|
||||
rofi_theme_widget_add_properties(parent, child->properties);
|
||||
return;
|
||||
}
|
||||
|
||||
ThemeWidget *w = rofi_theme_find_or_create_name(parent, child->name);
|
||||
rofi_theme_widget_add_properties(w, child->properties);
|
||||
for (unsigned int i = 0; i < child->num_widgets; i++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(w, child->widgets[i]);
|
||||
}
|
||||
}
|
||||
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child) {
|
||||
g_assert(parent != NULL);
|
||||
g_assert(child != NULL);
|
||||
@@ -1362,17 +1388,22 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
if (rwidget == NULL) {
|
||||
return;
|
||||
}
|
||||
for (unsigned int i = 0; i < rwidget->num_widgets; i++) {
|
||||
unsigned int i = 0;
|
||||
// for (unsigned int i = 0; i < rwidget->num_widgets; i++) {
|
||||
while (i < rwidget->num_widgets) {
|
||||
ThemeWidget *widget = rwidget->widgets[i];
|
||||
rofi_theme_parse_process_conditionals_int(mon, widget);
|
||||
if (widget->media != NULL) {
|
||||
rwidget->num_widgets--;
|
||||
for (unsigned x = i; x < rwidget->num_widgets; x++) {
|
||||
rwidget->widgets[x] = rwidget->widgets[x + 1];
|
||||
}
|
||||
rwidget->widgets[rwidget->num_widgets] = NULL;
|
||||
switch (widget->media->type) {
|
||||
case THEME_MEDIA_TYPE_MIN_WIDTH: {
|
||||
int w = widget->media->value;
|
||||
if (mon.w >= w) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1381,8 +1412,7 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
int w = widget->media->value;
|
||||
if (mon.w < w) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1391,9 +1421,9 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
int h = widget->media->value;
|
||||
if (mon.h >= h) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1401,8 +1431,7 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
int h = widget->media->value;
|
||||
if (mon.h < h) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1410,8 +1439,7 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
case THEME_MEDIA_TYPE_MON_ID: {
|
||||
if (mon.monitor_id == widget->media->value) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1420,8 +1448,7 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
double r = widget->media->value;
|
||||
if ((mon.w / (double)mon.h) >= r) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1430,8 +1457,7 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
double r = widget->media->value;
|
||||
if ((mon.w / (double)mon.h) < r) {
|
||||
for (unsigned int x = 0; x < widget->num_widgets; x++) {
|
||||
rofi_theme_parse_merge_widgets_no_media(rofi_theme,
|
||||
widget->widgets[x]);
|
||||
rofi_theme_parse_merge_widgets(rwidget, widget->widgets[x]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1440,6 +1466,11 @@ static void rofi_theme_parse_process_conditionals_int(workarea mon,
|
||||
break;
|
||||
}
|
||||
}
|
||||
rofi_theme_free(widget);
|
||||
// endif
|
||||
} else {
|
||||
rofi_theme_parse_process_conditionals_int(mon, widget);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -127,9 +127,8 @@ static void rofi_view_reload_message_bar(RofiViewState *state) {
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean rofi_view_user_timeout(G_GNUC_UNUSED gpointer data) {
|
||||
CacheState.user_timeout = 0;
|
||||
ThemeWidget *wid = rofi_config_find_widget("timeout", NULL, TRUE);
|
||||
static void rofi_view_take_action(const char *name) {
|
||||
ThemeWidget *wid = rofi_config_find_widget(name, NULL, TRUE);
|
||||
if (wid) {
|
||||
/** Check string property */
|
||||
Property *p = rofi_theme_find_property(wid, P_STRING, "action", TRUE);
|
||||
@@ -143,6 +142,10 @@ static gboolean rofi_view_user_timeout(G_GNUC_UNUSED gpointer data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static gboolean rofi_view_user_timeout(G_GNUC_UNUSED gpointer data) {
|
||||
CacheState.user_timeout = 0;
|
||||
rofi_view_take_action("timeout");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
@@ -446,7 +449,7 @@ static void update_callback(textbox *t, icon *ico, unsigned int index,
|
||||
list = pango_attr_list_new();
|
||||
}
|
||||
if (ico) {
|
||||
int icon_height = widget_get_desired_height(WIDGET(ico));
|
||||
int icon_height = widget_get_desired_height(WIDGET(ico), WIDGET(ico)->w);
|
||||
cairo_surface_t *icon =
|
||||
mode_get_icon(state->sw, state->line_map[index], icon_height);
|
||||
icon_set_surface(ico, icon);
|
||||
@@ -617,6 +620,12 @@ void rofi_view_finalize(RofiViewState *state) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should be called when the input of the entry is changed.
|
||||
* TODO: Evaluate if this needs to be a 'signal' on textbox?
|
||||
*/
|
||||
static void rofi_view_input_changed() { rofi_view_take_action("inputchange"); }
|
||||
|
||||
static void rofi_view_trigger_global_action(KeyBindingAction action) {
|
||||
RofiViewState *state = rofi_view_get_active();
|
||||
switch (action) {
|
||||
@@ -822,6 +831,7 @@ static void rofi_view_trigger_global_action(KeyBindingAction action) {
|
||||
if (rc == 1) {
|
||||
// Entry changed.
|
||||
state->refilter = TRUE;
|
||||
rofi_view_input_changed();
|
||||
} else if (rc == 2) {
|
||||
// Movement.
|
||||
}
|
||||
@@ -911,6 +921,7 @@ gboolean rofi_view_trigger_action(RofiViewState *state, BindingsScope scope,
|
||||
void rofi_view_handle_text(RofiViewState *state, char *text) {
|
||||
if (textbox_append_text(state->text, text, strlen(text))) {
|
||||
state->refilter = TRUE;
|
||||
rofi_view_input_changed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,9 +987,13 @@ static WidgetTriggerActionResult textbox_button_trigger_action(
|
||||
switch (action) {
|
||||
case MOUSE_CLICK_DOWN: {
|
||||
const char *type = rofi_theme_get_string(wid, "action", NULL);
|
||||
if (type) {
|
||||
(state->selected_line) =
|
||||
state->line_map[listview_get_selected(state->list_view)];
|
||||
if (type ) {
|
||||
if ( state->list_view) {
|
||||
(state->selected_line) =
|
||||
state->line_map[listview_get_selected(state->list_view)];
|
||||
} else {
|
||||
(state->selected_line) = UINT32_MAX;
|
||||
}
|
||||
guint id = key_binding_get_action_from_name(type);
|
||||
if (id != UINT32_MAX) {
|
||||
rofi_view_trigger_global_action(id);
|
||||
@@ -1277,8 +1292,6 @@ RofiViewState *rofi_view_create(Mode *sw, const char *input,
|
||||
state->distance = (int *)g_malloc0_n(state->num_lines, sizeof(int));
|
||||
|
||||
rofi_view_calculate_window_width(state);
|
||||
// Need to resize otherwise calculated desired height is wrong.
|
||||
widget_resize(WIDGET(state->main_window), state->width, 100);
|
||||
// Only needed when window is fixed size.
|
||||
if ((CacheState.flags & MENU_NORMAL_WINDOW) == MENU_NORMAL_WINDOW) {
|
||||
listview_set_fixed_num_lines(state->list_view);
|
||||
@@ -1341,10 +1354,7 @@ int rofi_view_error_dialog(const char *msg, int markup) {
|
||||
listview_set_fixed_num_lines(state->list_view);
|
||||
}
|
||||
rofi_view_calculate_window_width(state);
|
||||
// Need to resize otherwise calculated desired height is wrong.
|
||||
widget_resize(WIDGET(state->main_window), state->width, 100);
|
||||
// resize window vertically to suit
|
||||
state->height = widget_get_desired_height(WIDGET(state->main_window));
|
||||
state->height = rofi_view_calculate_window_height(state);
|
||||
|
||||
// Calculate window position.
|
||||
rofi_view_calculate_window_position(state);
|
||||
|
@@ -379,7 +379,7 @@ static int wayland_rofi_view_calculate_window_height(RofiViewState *state) {
|
||||
// Autosize based on widgets.
|
||||
widget *main_window = WIDGET(state->main_window);
|
||||
|
||||
height = widget_get_desired_height(main_window);
|
||||
height = widget_get_desired_height(main_window, state->width);
|
||||
return height;
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,7 @@ struct _box {
|
||||
|
||||
static void box_update(widget *wid);
|
||||
|
||||
static int box_get_desired_width(widget *wid) {
|
||||
static int box_get_desired_width(widget *wid, const int height) {
|
||||
box *b = (box *)wid;
|
||||
int spacing = distance_get_pixel(b->spacing, b->type);
|
||||
int width = 0;
|
||||
@@ -71,10 +71,10 @@ static int box_get_desired_width(widget *wid) {
|
||||
}
|
||||
active_widgets++;
|
||||
if (child->expand == TRUE) {
|
||||
width += widget_get_desired_width(child);
|
||||
width += widget_get_desired_width(child, height);
|
||||
continue;
|
||||
}
|
||||
width += widget_get_desired_width(child);
|
||||
width += widget_get_desired_width(child, height);
|
||||
}
|
||||
if (active_widgets > 0) {
|
||||
width += (active_widgets - 1) * spacing;
|
||||
@@ -86,13 +86,13 @@ static int box_get_desired_width(widget *wid) {
|
||||
if (!child->enabled) {
|
||||
continue;
|
||||
}
|
||||
width = MAX(widget_get_desired_width(child), width);
|
||||
width = MAX(widget_get_desired_width(child, height), width);
|
||||
}
|
||||
}
|
||||
width += widget_padding_get_padding_width(wid);
|
||||
return width;
|
||||
}
|
||||
static int box_get_desired_height(widget *wid) {
|
||||
static int box_get_desired_height(widget *wid, const int width) {
|
||||
box *b = (box *)wid;
|
||||
int spacing = distance_get_pixel(b->spacing, b->type);
|
||||
int height = 0;
|
||||
@@ -105,7 +105,7 @@ static int box_get_desired_height(widget *wid) {
|
||||
continue;
|
||||
}
|
||||
active_widgets++;
|
||||
height += widget_get_desired_height(child);
|
||||
height += widget_get_desired_height(child, width);
|
||||
}
|
||||
if (active_widgets > 0) {
|
||||
height += (active_widgets - 1) * spacing;
|
||||
@@ -117,7 +117,7 @@ static int box_get_desired_height(widget *wid) {
|
||||
if (!child->enabled) {
|
||||
continue;
|
||||
}
|
||||
height = MAX(widget_get_desired_height(child), height);
|
||||
height = MAX(widget_get_desired_height(child, width), height);
|
||||
}
|
||||
}
|
||||
height += widget_padding_get_padding_height(wid);
|
||||
@@ -134,7 +134,8 @@ static void vert_calculate_size(box *b) {
|
||||
iter = g_list_next(iter)) {
|
||||
widget *child = (widget *)iter->data;
|
||||
if (child->enabled && child->expand == FALSE) {
|
||||
widget_resize(child, rem_width, widget_get_desired_height(child));
|
||||
widget_resize(child, rem_width,
|
||||
widget_get_desired_height(child, rem_width));
|
||||
}
|
||||
}
|
||||
b->max_size = 0;
|
||||
@@ -201,7 +202,7 @@ static void hori_calculate_size(box *b) {
|
||||
widget *child = (widget *)iter->data;
|
||||
if (child->enabled && child->expand == FALSE) {
|
||||
widget_resize(child,
|
||||
widget_get_desired_width(child), // child->w,
|
||||
widget_get_desired_width(child, rem_height), // child->w,
|
||||
rem_height);
|
||||
}
|
||||
}
|
||||
|
@@ -41,11 +41,11 @@ struct _container {
|
||||
|
||||
static void container_update(widget *wid);
|
||||
|
||||
static int container_get_desired_height(widget *widget) {
|
||||
static int container_get_desired_height(widget *widget, const int width) {
|
||||
container *b = (container *)widget;
|
||||
int height = 0;
|
||||
if (b->child) {
|
||||
height += widget_get_desired_height(b->child);
|
||||
height += widget_get_desired_height(b->child, width);
|
||||
}
|
||||
height += widget_padding_get_padding_height(widget);
|
||||
return height;
|
||||
|
@@ -52,7 +52,8 @@ struct _icon {
|
||||
cairo_surface_t *icon;
|
||||
};
|
||||
|
||||
static int icon_get_desired_height(widget *widget) {
|
||||
static int icon_get_desired_height(widget *widget,
|
||||
G_GNUC_UNUSED const int width) {
|
||||
icon *b = (icon *)widget;
|
||||
int height = b->size;
|
||||
if (b->squared == FALSE) {
|
||||
@@ -67,7 +68,8 @@ static int icon_get_desired_height(widget *widget) {
|
||||
height += widget_padding_get_padding_height(widget);
|
||||
return height;
|
||||
}
|
||||
static int icon_get_desired_width(widget *widget) {
|
||||
static int icon_get_desired_width(widget *widget,
|
||||
G_GNUC_UNUSED const int height) {
|
||||
icon *b = (icon *)widget;
|
||||
int width = b->size;
|
||||
if (b->squared == FALSE) {
|
||||
|
@@ -206,7 +206,7 @@ static void listview_create_row(listview *lv, _listview_row *row) {
|
||||
g_list_free_full(list, g_free);
|
||||
}
|
||||
|
||||
static int listview_get_desired_height(widget *wid);
|
||||
static int listview_get_desired_height(widget *wid, const int width);
|
||||
|
||||
static void listview_free(widget *wid) {
|
||||
listview *lv = (listview *)wid;
|
||||
@@ -319,7 +319,8 @@ static void barview_draw(widget *wid, cairo_t *draw) {
|
||||
if (lv->barview.direction == LEFT_TO_RIGHT) {
|
||||
for (unsigned int i = 0; i < max && width > 0; i++) {
|
||||
update_element(lv, i, i + offset, TRUE);
|
||||
int twidth = widget_get_desired_width(WIDGET(lv->boxes[i].box));
|
||||
int twidth = widget_get_desired_width(WIDGET(lv->boxes[i].box),
|
||||
lv->element_height);
|
||||
if (twidth >= width) {
|
||||
if (!first) {
|
||||
break;
|
||||
@@ -339,7 +340,8 @@ static void barview_draw(widget *wid, cairo_t *draw) {
|
||||
for (unsigned int i = 0;
|
||||
i < lv->cur_elements && width > 0 && i <= offset; i++) {
|
||||
update_element(lv, i, offset - i, TRUE);
|
||||
int twidth = widget_get_desired_width(WIDGET(lv->boxes[i].box));
|
||||
int twidth = widget_get_desired_width(WIDGET(lv->boxes[i].box),
|
||||
lv->element_height);
|
||||
if (twidth >= width) {
|
||||
if (!first) {
|
||||
break;
|
||||
@@ -651,7 +653,7 @@ static gboolean listview_element_motion_notify(widget *wid,
|
||||
unsigned int i;
|
||||
for (i = 0; i < max && WIDGET(lv->boxes[i].box) != wid; i++) {
|
||||
}
|
||||
if (i < max && i != listview_get_selected(lv)) {
|
||||
if (i < max && (lv->last_offset + i) != listview_get_selected(lv)) {
|
||||
listview_set_selected(lv, lv->last_offset + i);
|
||||
}
|
||||
return TRUE;
|
||||
@@ -687,7 +689,8 @@ listview *listview_create(widget *parent, const char *name,
|
||||
};
|
||||
textbox_text(row.textbox, buff);
|
||||
}
|
||||
lv->element_height = widget_get_desired_height(WIDGET(row.box));
|
||||
// Make textbox very wide.
|
||||
lv->element_height = widget_get_desired_height(WIDGET(row.box), 100000);
|
||||
widget_free(WIDGET(row.box));
|
||||
|
||||
lv->callback = cb;
|
||||
@@ -877,7 +880,8 @@ void listview_nav_page_next(listview *lv) {
|
||||
}
|
||||
}
|
||||
|
||||
static int listview_get_desired_height(widget *wid) {
|
||||
static int listview_get_desired_height(widget *wid,
|
||||
G_GNUC_UNUSED const int width) {
|
||||
listview *lv = (listview *)wid;
|
||||
if (lv == NULL || lv->widget.enabled == FALSE) {
|
||||
return 0;
|
||||
|
@@ -39,7 +39,8 @@
|
||||
static void scrollbar_draw(widget *, cairo_t *);
|
||||
static void scrollbar_free(widget *);
|
||||
|
||||
static int scrollbar_get_desired_height(widget *wid) {
|
||||
static int scrollbar_get_desired_height(widget *wid,
|
||||
G_GNUC_UNUSED const int width) {
|
||||
// Want height we are.
|
||||
return wid->h;
|
||||
}
|
||||
|
@@ -75,16 +75,24 @@ static void textbox_resize(widget *wid, short w, short h) {
|
||||
textbox *tb = (textbox *)wid;
|
||||
textbox_moveresize(tb, tb->widget.x, tb->widget.y, w, h);
|
||||
}
|
||||
static int textbox_get_desired_height(widget *wid) {
|
||||
static int textbox_get_desired_height(widget *wid, const int width) {
|
||||
textbox *tb = (textbox *)wid;
|
||||
unsigned int offset = ((tb->flags & TB_INDICATOR) ? DOT_OFFSET : 0);
|
||||
if ((tb->flags & TB_AUTOHEIGHT) == 0) {
|
||||
return tb->widget.h;
|
||||
}
|
||||
if (tb->changed) {
|
||||
__textbox_update_pango_text(tb);
|
||||
}
|
||||
int old_width = pango_layout_get_width(tb->layout);
|
||||
pango_layout_set_width(
|
||||
tb->layout,
|
||||
PANGO_SCALE *
|
||||
(width - widget_padding_get_padding_width(WIDGET(tb)) - offset));
|
||||
|
||||
int height =
|
||||
textbox_get_estimated_height(tb, pango_layout_get_line_count(tb->layout));
|
||||
pango_layout_set_width(tb->layout, old_width);
|
||||
return height;
|
||||
}
|
||||
|
||||
@@ -314,14 +322,18 @@ void textbox_text(textbox *tb, const char *text) {
|
||||
g_free(tb->text);
|
||||
const gchar *last_pointer = NULL;
|
||||
|
||||
if (g_utf8_validate(text, -1, &last_pointer)) {
|
||||
tb->text = g_strdup(text);
|
||||
if (text == NULL) {
|
||||
tb->text = g_strdup("Invalid string.");
|
||||
} else {
|
||||
if (last_pointer != NULL) {
|
||||
// Copy string up to invalid character.
|
||||
tb->text = g_strndup(text, (last_pointer - text));
|
||||
if (g_utf8_validate(text, -1, &last_pointer)) {
|
||||
tb->text = g_strdup(text);
|
||||
} else {
|
||||
tb->text = g_strdup("Invalid UTF-8 string.");
|
||||
if (last_pointer != NULL) {
|
||||
// Copy string up to invalid character.
|
||||
tb->text = g_strndup(text, (last_pointer - text));
|
||||
} else {
|
||||
tb->text = g_strdup("Invalid UTF-8 string.");
|
||||
}
|
||||
}
|
||||
}
|
||||
__textbox_update_pango_text(tb);
|
||||
@@ -898,7 +910,7 @@ int textbox_get_estimated_height(const textbox *tb, int eh) {
|
||||
int height = tb->tbfc->height;
|
||||
return (eh * height) + widget_padding_get_padding_height(WIDGET(tb));
|
||||
}
|
||||
int textbox_get_desired_width(widget *wid) {
|
||||
int textbox_get_desired_width(widget *wid, G_GNUC_UNUSED const int height) {
|
||||
if (wid == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
@@ -646,23 +646,23 @@ int widget_padding_get_padding_width(const widget *wid) {
|
||||
return width;
|
||||
}
|
||||
|
||||
int widget_get_desired_height(widget *wid) {
|
||||
int widget_get_desired_height(widget *wid, const int width) {
|
||||
if (wid == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (wid->get_desired_height == NULL) {
|
||||
return wid->h;
|
||||
}
|
||||
return wid->get_desired_height(wid);
|
||||
return wid->get_desired_height(wid, width);
|
||||
}
|
||||
int widget_get_desired_width(widget *wid) {
|
||||
int widget_get_desired_width(widget *wid, const int height) {
|
||||
if (wid == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (wid->get_desired_width == NULL) {
|
||||
return wid->w;
|
||||
}
|
||||
return wid->get_desired_width(wid);
|
||||
return wid->get_desired_width(wid, height);
|
||||
}
|
||||
|
||||
int widget_get_absolute_xpos(widget *wid) {
|
||||
|
24
source/xcb.c
24
source/xcb.c
@@ -63,6 +63,9 @@
|
||||
#include "xcb.h"
|
||||
#include <libsn/sn.h>
|
||||
|
||||
#include "dialogs/window.h"
|
||||
#include "mode.h"
|
||||
|
||||
#include <rofi.h>
|
||||
|
||||
/** Minimal randr preferred for running rofi (1.5) (Major version number) */
|
||||
@@ -1083,6 +1086,22 @@ static void main_loop_x11_event_handler_view(xcb_generic_event_t *event) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_DESTROY_NOTIFY: {
|
||||
xcb_window_t win = ((xcb_destroy_notify_event_t *)event)->window;
|
||||
if (win != rofi_view_get_window()) {
|
||||
window_client_handle_signal(win, FALSE);
|
||||
} else {
|
||||
g_main_loop_quit(xcb->main_loop);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_CREATE_NOTIFY: {
|
||||
xcb_window_t win = ((xcb_create_notify_event_t *)event)->window;
|
||||
if (win != rofi_view_get_window()) {
|
||||
window_client_handle_signal(win, TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_EXPOSE:
|
||||
rofi_view_frame_callback();
|
||||
break;
|
||||
@@ -1484,6 +1503,11 @@ gboolean display_setup(GMainLoop *main_loop, NkBindings *bindings) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint32_t val[] = {XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY};
|
||||
|
||||
xcb_change_window_attributes(xcb->connection, xcb_stuff_get_root_window(),
|
||||
XCB_CW_EVENT_MASK, val);
|
||||
|
||||
// startup not.
|
||||
xcb->sndisplay =
|
||||
sn_xcb_display_new(xcb->connection, error_trap_push, error_trap_pop);
|
||||
|
@@ -825,7 +825,7 @@ static int xcb_rofi_view_calculate_window_height(RofiViewState *state) {
|
||||
}
|
||||
// Autosize based on widgets.
|
||||
widget *main_window = WIDGET(state->main_window);
|
||||
return widget_get_desired_height(main_window);
|
||||
return widget_get_desired_height(main_window, state->width);
|
||||
}
|
||||
|
||||
static void xcb_rofi_view_hide(void) {
|
||||
|
@@ -549,7 +549,8 @@ void config_parse_cmd_options(void) {
|
||||
g_string_append(str, " } ");
|
||||
}
|
||||
if (rofi_theme_parse_string(str->str) == 1) {
|
||||
printf("failed\n");
|
||||
/** Failed to parse, try again as string. */
|
||||
rofi_clear_error_messages();
|
||||
}
|
||||
}
|
||||
g_string_free(str, TRUE);
|
||||
@@ -639,6 +640,22 @@ static gboolean __config_parser_set_property(XrmOption *option,
|
||||
}
|
||||
|
||||
gboolean config_parse_set_property(const Property *p, char **error) {
|
||||
if (g_ascii_strcasecmp(p->name, "theme") == 0) {
|
||||
if (p->type == P_STRING) {
|
||||
*error = g_strdup_printf("The option:\n<b>\nconfiguration\n{\n\ttheme: "
|
||||
"\"%s\";\n}</b>\nis deprecated. Please replace "
|
||||
"with: <b>@theme \"%s\"</b> "
|
||||
"after the configuration block.",
|
||||
p->value.s, p->value.s);
|
||||
} else {
|
||||
*error = g_strdup_printf("The option:\n<b>\nconfiguration\n{\n\ttheme: "
|
||||
"\"%s\";\n}</b>\nis deprecated. Please replace "
|
||||
"with: <b>@theme \"%s\"</b> "
|
||||
"after the configuration block.",
|
||||
"myTheme", "myTheme");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
for (unsigned int i = 0; i < sizeof(xrmOptions) / sizeof(XrmOption); ++i) {
|
||||
XrmOption *op = &(xrmOptions[i]);
|
||||
if (g_strcmp0(op->name, p->name) == 0) {
|
||||
@@ -651,21 +668,23 @@ gboolean config_parse_set_property(const Property *p, char **error) {
|
||||
return __config_parser_set_property(op, p, error);
|
||||
}
|
||||
}
|
||||
*error = g_strdup_printf("Option: %s is not found.", p->name);
|
||||
//*error = g_strdup_printf("Option: %s is not found.", p->name);
|
||||
g_warning("Option: %s is not found.", p->name);
|
||||
|
||||
|
||||
for (GList *iter = g_list_first(extra_parsed_options); iter != NULL;
|
||||
iter = g_list_next(iter)) {
|
||||
if (g_strcmp0(((Property *)(iter->data))->name, p->name) == 0) {
|
||||
rofi_theme_property_free((Property *)(iter->data));
|
||||
iter->data = (void *)rofi_theme_property_copy(p);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
g_debug("Adding option: %s to backup list.", p->name);
|
||||
extra_parsed_options =
|
||||
g_list_append(extra_parsed_options, rofi_theme_property_copy(p));
|
||||
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void config_xresource_free(void) {
|
||||
|
@@ -36,3 +36,8 @@ element {
|
||||
element selected {
|
||||
background-color: SteelBlue;
|
||||
}
|
||||
|
||||
element-text, element-icon {
|
||||
background-color: inherit;
|
||||
text-color: inherit;
|
||||
}
|
||||
|
@@ -83,7 +83,7 @@ element selected {
|
||||
background-color: lightgreen/20%;
|
||||
}
|
||||
|
||||
element-text {
|
||||
element-text, element-icon {
|
||||
font: inherit;
|
||||
horizontal-align: 0.5;
|
||||
}
|
||||
@@ -120,11 +120,12 @@ button {
|
||||
border-color: lightgreen;
|
||||
border-radius: 10px 10px 0 0;
|
||||
background-image: linear-gradient(to bottom, darkgreen/50%, black/70%);
|
||||
horizontal-align: 0.5;
|
||||
}
|
||||
button selected.normal {
|
||||
text-color: white;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
padding: 0px;
|
||||
|
||||
border: 5px 5px 0px ;
|
||||
border-color: lightgreen;
|
||||
|
Reference in New Issue
Block a user