Merge remote-tracking branch 'upstream/next' into wayland

This commit is contained in:
lbonn
2021-10-25 20:14:21 +02:00
47 changed files with 921 additions and 458 deletions

View File

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

View File

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

View 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 youre 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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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:
![positions](anchors.svg)
![location](anchors.svg)
## 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):
![positions](example-pos.png)
> 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;}"
```

View File

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

View File

@@ -1,3 +1,4 @@
.nh
.TH rofi\-sensible\-terminal 1 rofi\-sensible\-terminal
.SH NAME
.PP

View File

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

View File

@@ -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\-\&section 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 | | | |
| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | | |
| | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | |
| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |
|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-|

View File

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

View File

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

View 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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',
]),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -36,3 +36,8 @@ element {
element selected {
background-color: SteelBlue;
}
element-text, element-icon {
background-color: inherit;
text-color: inherit;
}

View File

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