Merge tag '1.7.0' into wayland

This commit is contained in:
lbonn 2021-09-06 13:11:14 +02:00
commit cfc3be4a5d
81 changed files with 3405 additions and 1046 deletions

View file

@ -10,6 +10,7 @@ your description.
This is an attempt to keep the issue tracker clean and searchable. This is an attempt to keep the issue tracker clean and searchable.
Questions or discussions about new features belong on Questions or discussions about new features belong on
[GITHUB Discussions](https://github.com/davatorium/rofi/discussions) or
[FORUM](https://reddit.com/r/qtools/), [FORUM](https://reddit.com/r/qtools/),
[IRC](https://webchat.freenode.net/?channels=#rofi), frequently asked questions [IRC](https://webchat.freenode.net/?channels=#rofi), frequently asked questions
will be added to the [F.A.Q](https://github.com/DaveDavenport/rofi/wiki#faq) on will be added to the [F.A.Q](https://github.com/DaveDavenport/rofi/wiki#faq) on
@ -19,6 +20,7 @@ Questions filled in on the bug tracker will be marked `question`, locked and
closed. closed.
It is preferred to have feature requests discussed via It is preferred to have feature requests discussed via
[GITHUB Discussions](https://github.com/davatorium/rofi/discussions) or
[FORUM](https://reddit.com/r/qtools/) or [FORUM](https://reddit.com/r/qtools/) or
[IRC](https://webchat.freenode.net/?channels=#rofi) first. [IRC](https://webchat.freenode.net/?channels=#rofi) first.

View file

@ -10,6 +10,10 @@ First read the [guidelines](https://github.com/DaveDavenport/rofi/blob/next/.git
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. 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. 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. 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: :exclamation:
## Version ## Version

View file

@ -11,6 +11,10 @@ First read the [guidelines](https://github.com/DaveDavenport/rofi/blob/next/.git
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. 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. 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. 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: :exclamation:
## Before creating a feature request ## Before creating a feature request

39
.github/actions/autotools/action.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: Autotools Build
description: Builds Rofi using Autotools
inputs:
cc:
description: Compiler to use
required: true
runs:
using: composite
steps:
- id: setup
run: |
autoreconf --install
mkdir builddir && cd builddir
../configure CC=${{ inputs.cc }}
shell: bash
- id: build
run: cd builddir && make
shell: bash
- id: test
run: cd builddir && make distcheck
shell: bash
- id: doxy
run: cd builddir && make doxy 2>&1 > doxygen.log
shell: bash
- id: doxycheck
uses: ./.github/actions/doxycheck
with:
logfile: builddir/doxygen.log
- id: upload
uses: actions/upload-artifact@v2
with:
name: tarballs
path: |
builddir/*.tar.gz
builddir/*.tar.xz

24
.github/actions/doxycheck/action.yml vendored Normal file
View file

@ -0,0 +1,24 @@
name: Doxygen Check
description: Checks for Doxygen warnings
inputs:
logfile:
description: Path to doxygen logfile
required: true
runs:
using: composite
steps:
- id: check
run: |
if [[ "$(grep -c warning ${{ inputs.logfile }})" != 0 ]]; then
echo
echo Doxygen warnings found:
grep warning ${{ inputs.logfile }}
echo
exit 1
fi
python2 ./doxy-coverage/doxy-coverage.py builddir/doc/html/xml/
shell: bash

32
.github/actions/meson/action.yml vendored Normal file
View file

@ -0,0 +1,32 @@
name: Meson Build
description: Builds Rofi using Meson
inputs:
cc:
description: Compiler to use
required: true
runs:
using: composite
steps:
- id: pip
run: pip install meson ninja
shell: bash
- id: setup
run: meson setup builddir -Db_coverage=true
shell: bash
env:
CC: ${{ inputs.cc }}
- id: build
run: ninja -C builddir
shell: bash
- id: test
run: ninja -C builddir test
shell: bash
- id: doxy
run: ninja -C builddir doc/html 2>&1 > doxygen.log
shell: bash
- id: doxycheck
uses: ./.github/actions/doxycheck
with:
logfile: doxygen.log

56
.github/actions/setup/action.yml vendored Normal file
View file

@ -0,0 +1,56 @@
name: CI Build Setup
description: Sets up build dependencies
runs:
using: composite
steps:
- id: python
uses: actions/setup-python@v1
with:
python-version: '3.x'
- id: apt
run: |
sudo apt-get install -y \
discount \
doxygen \
fluxbox \
gdb \
graphviz \
jq \
lcov \
libpango1.0-dev \
libstartup-notification0-dev \
libxcb-ewmh-dev \
libxcb-icccm4-dev \
libxcb-randr0-dev \
libxcb-util0-dev \
libxcb-xinerama0-dev \
libxcb-xkb-dev \
libxcb-xrm-dev \
libxcb-cursor-dev \
libxkbcommon-dev \
libxkbcommon-dev \
libxkbcommon-x11-dev \
ninja-build \
python3-pip \
python3-setuptools \
python3-wheel \
texi2html \
texinfo \
xdotool \
xfonts-base \
xterm \
xutils-dev
shell: bash
- id: doxy
run: git clone https://github.com/alobbs/doxy-coverage
shell: bash
- id: check
run: |
curl -L https://github.com/libcheck/check/releases/download/0.14.0/check-0.14.0.tar.gz | tar xzf -
cd check-0.14.0
./configure
make
sudo make install
sudo ldconfig
shell: bash

57
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,57 @@
name: CI Build
on:
push:
branches:
- next
paths-ignore:
- "**.md"
- "**.markdown"
- "**.rasi"
pull_request:
paths-ignore:
- "**.md"
- "**.markdown"
- "**.rasi"
jobs:
build-meson-gcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: ./.github/actions/setup
- uses: ./.github/actions/meson
with:
cc: gcc
build-meson-clang:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: ./.github/actions/setup
- uses: ./.github/actions/meson
with:
cc: clang
build-autotools-gcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: ./.github/actions/setup
- uses: ./.github/actions/autotools
with:
cc: gcc
build-autotools-clang:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: ./.github/actions/setup
- uses: ./.github/actions/autotools
with:
cc: clang

View file

@ -1,3 +1,47 @@
v1.7.0: Iggy 2024
- ADD: -steal-focus option.
- ADD: [Config] Add nested configuration option support.
- ADD: [Config] Support for handling dynamic config options.
- ADD: [IconFetcher] Find images shipped with the theme.
- ADD: [DRun] Add support for passing file (using file-browser) completer for desktop files that support his.
- ADD: [DRun] Support for service files.
- ADD: [FileBrowser] Allow setting startup directory (#1325)
- ADD: [FileBrowser]: Add sorting-method. (#1340)
- ADD: [FileBrowser] Add option to group directories ahead of files. (#1352)
- ADD: [Filtering] Add prefix matching method. (#1237)
- ADD: [Icon] Add option to square the widget.
- ADD: [Icon|Button] Make action available on icon, button and keybinding name.
- ADD: [KeyBinding] Add Ctrl-Shift-Enter option. (#874)
- ADD: [ListView]-hover-select option. (#1234)
- ADD: [Run] Add support for passing file (using file-browser) completer.
- ADD: [Textbox] Allow theme to force markup on text widget.
- ADD: [Theme] theme validation option. (`-rasi-validate`)
- ADD: [View] Add support for user timeout and keybinding action.
- ADD: [Widget] Add cursor property (#1313)
- ADD: [Widget] Add scaling option to background-image.
- ADD: [Widget] Add support background-image and lineair gradient option.
- ADD: [Window] Add pango markup for window format (#1288)
- ADD: [Window] Allow rofi to stay open after closing window.
- FIX: [DSL] Move theme reset into grammar parser from lexer.
- FIX: [Drun]: fix sorting on broken desktop files. (thanks to nick87720z)
- FIX: [File Browser]: Fix escaping of paths.
- FIX: [ListView] Fix wrong subwidget name.
- FIX: [Script] Don't enable custom keybindings by default.
- FIX: [TextBox] Fix height estimation.
- FIX: [Theme] widget state and inherited properties. This should help fixing some old themes with changes from 1.6.1.
- FIX: [Widget] Fix rendering of border and dashes. (Thanks to nick87720z)
- FIX: [Build] Fix CI.
- FIX: [Theme] Discard old theme, when explicitly passing one on command line.
- REMOVE: -dump-xresources
- REMOVE: -fullscreen
- REMOVE: -show-match
- REMOVE: Old xresources based configuration file.
- REMOVE: fake transparency/background option, part of theme now.
- REMOVE: xresources parsing via Xserver
- Remove: [Theme] Remove backwards compatiblity hack.
- DOC: Update changes to manpages
v1.6.1: Tortoise Power v1.6.1: Tortoise Power
- Use GdkPixbuf for Icon parsing. - Use GdkPixbuf for Icon parsing.
- Add FileBrowser to default mode. - Add FileBrowser to default mode.

View file

@ -255,8 +255,8 @@ EXTRA_DIST+=\
doc/rofi.doxy.in\ doc/rofi.doxy.in\
script/get_git_rev.sh\ script/get_git_rev.sh\
$(theme_DATA)\ $(theme_DATA)\
doc/default_theme.rasi\
doc/default_configuration.rasi\ doc/default_configuration.rasi\
doc/default_theme.rasi\
Changelog Changelog
## ##
# Indent # Indent
@ -328,6 +328,7 @@ textbox_test_CFLAGS=\
-I$(top_builddir)/lexer/\ -I$(top_builddir)/lexer/\
-I$(top_srcdir)/lexer/\ -I$(top_srcdir)/lexer/\
-I$(top_srcdir)/config/\ -I$(top_srcdir)/config/\
-I$(top_builddir)/resources/\
-I$(top_builddir)/ -I$(top_builddir)/
textbox_test_LDADD=\ textbox_test_LDADD=\
@ -368,7 +369,8 @@ widget_test_SOURCES=\
config/config.c\ config/config.c\
lexer/theme-parser.y\ lexer/theme-parser.y\
lexer/theme-lexer.l\ lexer/theme-lexer.l\
test/widget-test.c test/widget-test.c\
resources/resources.c
box_test_LDADD=$(textbox_test_LDADD) box_test_LDADD=$(textbox_test_LDADD)
box_test_CFLAGS=$(textbox_test_CFLAGS) box_test_CFLAGS=$(textbox_test_CFLAGS)
@ -384,6 +386,7 @@ box_test_SOURCES=\
include/theme.h\ include/theme.h\
include/css-colors.h\ include/css-colors.h\
config/config.c\ config/config.c\
resources/resources.c\
test/box-test.c test/box-test.c
scrollbar_test_LDADD=$(textbox_test_LDADD) scrollbar_test_LDADD=$(textbox_test_LDADD)
@ -400,7 +403,8 @@ scrollbar_test_SOURCES=\
include/theme.h\ include/theme.h\
include/css-colors.h\ include/css-colors.h\
config/config.c\ config/config.c\
test/scrollbar-test.c test/scrollbar-test.c\
resources/resources.c
textbox_test_SOURCES=\ textbox_test_SOURCES=\
source/widgets/widget.c\ source/widgets/widget.c\
@ -424,6 +428,7 @@ textbox_test_SOURCES=\
include/xrmoptions.h\ include/xrmoptions.h\
include/helper.h\ include/helper.h\
include/helper-theme.h\ include/helper-theme.h\
resources/resources.c\
test/textbox-test.c test/textbox-test.c
if USE_CHECK if USE_CHECK
@ -448,6 +453,7 @@ theme_parser_test_SOURCES=\
source/rofi-types.c\ source/rofi-types.c\
include/rofi-types.h\ include/rofi-types.h\
source/css-colors.c\ source/css-colors.c\
resources/resources.c\
test/theme-parser-test.c test/theme-parser-test.c
endif endif
@ -481,6 +487,7 @@ helper_test_CFLAGS=\
-I$(top_builddir)/lexer/\ -I$(top_builddir)/lexer/\
-I$(top_srcdir)/lexer/\ -I$(top_srcdir)/lexer/\
-I$(top_srcdir)/config/\ -I$(top_srcdir)/config/\
-I$(top_builddir)/resources/\
-I$(top_builddir)/ -I$(top_builddir)/
helper_test_LDADD=\ helper_test_LDADD=\
@ -579,16 +586,6 @@ TESTS+=theme_parser_test\
mode_test mode_test
endif endif
.PHONY: test-x
test-x: $(bin_PROGRAMS)
MESON_SOURCE_ROOT="$(top_srcdir)" \
MESON_BUILD_ROOT="$(top_builddir)" \
$(top_srcdir)/test/run_all_tests.sh
.PHONY: indent
indent: $(SOURCES)
uncrustify -c $(top_srcdir)/data/uncrustify.cfg --replace $^
.PHONY: cppcheck .PHONY: cppcheck
cppcheck: $(rofi_SOURCES) cppcheck: $(rofi_SOURCES)
cppcheck --std=c99 --platform=unix64 --enable=all -Uerror_dialog --inconclusive -I $(top_srcdir)/include/ $^ cppcheck --std=c99 --platform=unix64 --enable=all -Uerror_dialog --inconclusive -I $(top_srcdir)/include/ $^

View file

@ -1,12 +1,8 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/ca0310962a7c4b829d0c57f1ab023531)](https://app.codacy.com/app/davatorium/rofi?utm_source=github.com\&utm_medium=referral\&utm_content=davatorium/rofi\&utm_campaign=Badge_Grade_Settings)
[![Build Status](https://travis-ci.org/davatorium/rofi.svg?branch=master)](https://travis-ci.org/davatorium/rofi)
[![codecov.io](https://codecov.io/github/davatorium/rofi/coverage.svg?branch=master)](https://codecov.io/github/davatorium/rofi?branch=master)
[![Issues](https://img.shields.io/github/issues/davatorium/rofi.svg)](https://github.com/davatorium/rofi/issues) [![Issues](https://img.shields.io/github/issues/davatorium/rofi.svg)](https://github.com/davatorium/rofi/issues)
[![Forks](https://img.shields.io/github/forks/davatorium/rofi.svg)](https://github.com/davatorium/rofi/network) [![Forks](https://img.shields.io/github/forks/davatorium/rofi.svg)](https://github.com/davatorium/rofi/network)
[![Stars](https://img.shields.io/github/stars/davatorium/rofi.svg)](https://github.com/davatorium/rofi/stargazers) [![Stars](https://img.shields.io/github/stars/davatorium/rofi.svg)](https://github.com/davatorium/rofi/stargazers)
[![Downloads](https://img.shields.io/github/downloads/davatorium/rofi/total.svg)](https://github.com/davatorium/rofi/releases) [![Downloads](https://img.shields.io/github/downloads/davatorium/rofi/total.svg)](https://github.com/davatorium/rofi/releases)
[![Coverity](https://scan.coverity.com/projects/3850/badge.svg)](https://scan.coverity.com/projects/davedavenport-rofi) [![Forum](https://img.shields.io/badge/forum-online-green.svg)](https://github.com/davatorium/rofi/discussions)
[![Forum](https://img.shields.io/badge/forum-online-green.svg)](https://reddit.com/r/qtools/)
[![Packages](https://repology.org/badge/tiny-repos/rofi.svg)](https://repology.org/metapackage/rofi/versions) [![Packages](https://repology.org/badge/tiny-repos/rofi.svg)](https://repology.org/metapackage/rofi/versions)
# A window switcher, Application launcher and dmenu replacement # A window switcher, Application launcher and dmenu replacement

View file

@ -1,4 +1,4 @@
AC_INIT([rofi], [1.6.1-dev], [https://github.com/davatorium/rofi/],[],[https://reddit.com/r/qtools/]) AC_INIT([rofi], [1.7.0], [https://github.com/davatorium/rofi/],[],[https://reddit.com/r/qtools/])
AC_CONFIG_SRCDIR([source/rofi.c]) AC_CONFIG_SRCDIR([source/rofi.c])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])

View file

@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150.71399mm"
height="69.147636mm"
viewBox="0 0 150.71399 69.147635"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r"
sodipodi:docname="anchors.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.8246591"
inkscape:cx="302.5802"
inkscape:cy="62.615586"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1886"
inkscape:window-height="1006"
inkscape:window-x="15"
inkscape:window-y="57"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
scale-x="0.99999998">
<inkscape:grid
type="xygrid"
id="grid3682"
originx="16.324069"
originy="-137.50508" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(16.324071,-90.347289)">
<rect
id="rect3680"
width="113.59723"
height="53.512745"
x="3.4443808"
y="98.826805"
style="fill:none;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="49.48209"
y="122.17239"
id="text4491"><tspan
sodipodi:role="line"
id="tspan4489"
x="49.48209"
y="122.17239"
style="stroke-width:0.16429351">center</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="51.163532"
y="159.22668"
id="text4491-3"><tspan
sodipodi:role="line"
id="tspan4489-6"
x="51.163532"
y="159.22668"
style="stroke-width:0.16429351">south</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="120.4699"
y="127.84382"
id="text4491-7"><tspan
sodipodi:role="line"
id="tspan4489-5"
x="120.4699"
y="127.84382"
style="stroke-width:0.16429351">east</tspan></text>
<g
id="g4539"
transform="matrix(0.62095187,0,0,0.62095187,-8.1591307,61.340986)">
<text
id="text4491-35"
y="107.09821"
x="-13.593488"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="107.09821"
x="-13.593488"
id="tspan4489-62"
sodipodi:role="line">west</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="-16.920919"
y="95.340271"
id="text4491-9"><tspan
sodipodi:role="line"
id="tspan4489-1"
x="-16.920919"
y="95.340271"
style="stroke-width:0.16429351">northwest</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="102.82118"
y="95.340271"
id="text4491-9-2"><tspan
sodipodi:role="line"
id="tspan4489-1-7"
x="102.82118"
y="95.340271"
style="stroke-width:0.16429351">northeast</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="-16.680254"
y="159.22668"
id="text4491-9-0"><tspan
sodipodi:role="line"
id="tspan4489-1-9"
x="-16.680254"
y="159.22668"
style="stroke-width:0.16429351">southwest</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="102.1024"
y="159.22668"
id="text4491-9-2-3"><tspan
sodipodi:role="line"
id="tspan4489-1-7-6"
x="102.1024"
y="159.22668"
style="stroke-width:0.16429351">southeast</tspan></text>
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601"
width="5.7502732"
height="4.1073375"
x="0.38413191"
y="97.014793" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-0"
width="5.7502732"
height="4.107338"
x="57.367859"
y="97.014793" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-6"
width="5.7502732"
height="4.107338"
x="113.74665"
y="97.014793" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-2"
width="5.7502732"
height="4.107338"
x="0.8770141"
y="149.75291" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-0-6"
width="5.7502732"
height="4.107338"
x="57.367859"
y="149.75291" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-6-1"
width="5.7502732"
height="4.107338"
x="114.23956"
y="149.75291" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-02"
width="5.7502732"
height="4.107338"
x="0.21978256"
y="123.52951" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-6-3"
width="5.7502732"
height="4.107338"
x="113.5826"
y="123.52951" />
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.24190378;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4601-0-7"
width="5.7502732"
height="4.107338"
x="57.367859"
y="124.12322" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:6.57174015px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.16429351"
x="51.204075"
y="95.340271"
id="text4491-5"><tspan
sodipodi:role="line"
id="tspan4489-9"
x="51.204075"
y="95.340271"
style="stroke-width:0.16429351">north</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 KiB

View file

@ -0,0 +1,68 @@
# Positioning Rofi on the monitor
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
second what point of the **rofi** window connects there. This sounds
complicated, but it ain't.
## position setting
The position setting determines the place of the window on the monitor.
The position setting supports the following values:
* north
* northeast
* northwest
* south
* southeast
* southwest
* east
* west
* center
This is depicted in the diagram below:
![positions](anchors.svg)
## anchor setting
The anchor sets what point of the **rofi** window is placed at the specified *position*.
The *anchor* settings supports the same values as the *position* setting.
If you want the middle of the **rofi** window to be always located at the center of the monitor set both *position* 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.
> Note that if you set the *anchor* to `south` and the *position* to `north` the **rofi** window will be placed above
> the monitor and might not be visible.
> In another blog post we will explain how the dynamic sizing behaviour of **rofi** can be tweaked or disabled.
So the following theme setting will place the top of the **rofi** window in the center of the monitor:
```css
window {
position: center;
anchor: north;
}
```
As depicted here, RED is the position (center of screen), GREEN is the position 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;}"
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 764 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1,520 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="140.56444mm"
height="125.35348mm"
viewBox="0 0 498.06297 444.16587"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
sodipodi:docname="structure.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.3109114"
inkscape:cx="207.81695"
inkscape:cy="278.27806"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1080"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid4136"
originx="-16.716536"
originy="-583.64568" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-16.716536,-24.550682)">
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4138"
width="460.62991"
height="389.76379"
x="35.433071"
y="60.236221" />
<rect
style="fill:none;fill-opacity:1;stroke:#009500;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4173"
width="425.19684"
height="53.149605"
x="53.149605"
y="77.952759" />
<rect
style="fill:none;fill-opacity:1;stroke:#950006;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4173-3"
width="426.23825"
height="53.072773"
x="52.108196"
y="379.21069" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="143.5146"
y="416.61566"
id="text4258-9"><tspan
sodipodi:role="line"
id="tspan4260-3"
x="143.5146"
y="416.61566"
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1">button</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#ff8500;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4352"
width="425.19684"
height="141.73228"
x="53.149605"
y="219.68504"
ry="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="22.945978"
y="55.447983"
id="text4443"><tspan
sodipodi:role="line"
id="tspan4445"
x="22.945978"
y="55.447983"
style="font-size:12.5px;line-height:1.25">#window</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="41.054344"
y="73.785233"
id="text4443-9"><tspan
sodipodi:role="line"
id="tspan4445-2"
x="41.054344"
y="73.785233"
style="font-size:12.5px;line-height:1.25">#window mainbox</tspan></text>
<g
id="g4725"
transform="translate(275.25999,21.315025)">
<text
id="text4443-9-9-1-4-3"
y="13.202698"
x="141.91444"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:12.5px;line-height:1.25"
y="13.202698"
x="141.91444"
id="tspan4445-2-7-2-7-6"
sodipodi:role="line">+</tspan></text>
<text
id="text4443-9-9-1-4-1"
y="12.732727"
x="156.55943"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:12.5px;line-height:1.25"
y="12.732727"
x="156.55943"
id="tspan4445-2-7-2-7-06"
sodipodi:role="line">Expand</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="326.40759"
y="119.25806"
id="text4443-9-9-1-4-3-3"><tspan
sodipodi:role="line"
id="tspan4445-2-7-2-7-6-2"
x="326.40759"
y="119.25806"
style="font-size:12.5px;line-height:1.25">+</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="453.20245"
y="232.17642"
id="text4443-9-9-1-4-3-3-0"><tspan
sodipodi:role="line"
id="tspan4445-2-7-2-7-6-2-6"
x="453.20245"
y="232.17642"
style="font-size:12.5px;line-height:1.25">+</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="60.590561"
y="231.79265"
id="text4443-9-9-1-4"><tspan
sodipodi:role="line"
id="tspan4445-2-7-2-7"
x="60.590561"
y="231.79265"
style="font-size:12.5px;line-height:1.25">#window mainbox listview</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#fabd00;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4211"
width="496.06299"
height="424.91339"
x="17.716536"
y="42.80315" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="60.544346"
y="91.87899"
id="text4443-9-6"><tspan
sodipodi:role="line"
id="tspan4445-2-75"
x="60.544346"
y="91.87899"
style="font-size:12.5px;line-height:1.25">#window mainbox inputbar</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="59.806118"
y="391.94498"
id="text4443-9-9-1-4-56"><tspan
sodipodi:role="line"
id="tspan4445-2-7-2-7-2"
x="59.806118"
y="391.94498"
style="font-size:12.5px;line-height:1.25">#window mainbox sidebar</tspan></text>
<g
id="g4383"
transform="translate(9.9192876,-6.5095325)">
<text
id="text4258"
y="120.80842"
x="69.25045"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="120.80842"
x="69.25045"
id="tspan4260"
sodipodi:role="line">prompt</tspan></text>
<rect
y="103.08986"
x="61.681175"
height="28.025009"
width="74.836868"
id="rect4300"
style="fill:none;fill-opacity:1;stroke:#950006;stroke-width:1.97499132;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4388"
transform="translate(12.39911,-6.5095325)">
<text
id="text4258-1"
y="120.51236"
x="217.36252"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="120.51236"
x="217.36252"
id="tspan4260-2"
sodipodi:role="line">entry</tspan></text>
<rect
y="103.09647"
x="134.63979"
height="28.011784"
width="205.52357"
id="rect4300-9"
style="fill:none;fill-opacity:1;stroke:#950006;stroke-width:1.98821568;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="355.36514"
y="116.18487"
id="text4258-1-7"><tspan
sodipodi:role="line"
id="tspan4260-2-0"
x="355.36514"
y="116.18487"
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1">case-indicator</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#950006;stroke-width:1.98826003;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4300-1"
width="113.39758"
height="28.01174"
x="352.07089"
y="96.586967" />
<rect
style="fill:none;fill-opacity:1;stroke:#009500;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4173-2"
width="194.88188"
height="28.346447"
x="70.866142"
y="396.8504" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="338.39648"
y="416.61566"
id="text4258-9-7"><tspan
sodipodi:role="line"
id="tspan4260-3-0"
x="338.39648"
y="416.61566"
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1">button</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#009500;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4173-2-9"
width="194.88191"
height="28.346447"
x="265.74802"
y="396.8504" />
<g
id="g4408"
transform="translate(6.5112369,-10.679593)">
<text
id="text4258-1-6"
y="266.72287"
x="101.68279"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="266.72287"
x="101.68279"
id="tspan4260-2-1"
sodipodi:role="line">Element</tspan></text>
<rect
y="248.08116"
x="64.000687"
height="28.346462"
width="141.73228"
id="rect4368"
style="fill:none;fill-opacity:1;stroke:#ffc602;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4505">
<rect
y="237.40157"
x="425.19687"
height="99.212601"
width="28.346449"
id="rect4354"
style="fill:none;fill-opacity:1;stroke:#cb71ff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
transform="rotate(-90)"
id="text4258-1-6-3"
y="444.96213"
x="-320.51251"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="444.96213"
x="-320.51251"
id="tspan4260-2-1-6"
sodipodi:role="line">Scrollbar</tspan></text>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="439.00262"
y="412.55084"
id="text4443-9-9-1-4-3-3-0-3"><tspan
sodipodi:role="line"
id="tspan4445-2-7-2-7-6-2-6-6"
x="439.00262"
y="412.55084"
style="font-size:12.5px;line-height:1.25">+</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="241.00262"
y="414.09415"
id="text4443-9-9-1-4-3-3-0-3-7"><tspan
sodipodi:role="line"
id="tspan4445-2-7-2-7-6-2-6-6-5"
x="241.00262"
y="414.09415"
style="font-size:12.5px;line-height:1.25">+</tspan></text>
<rect
style="fill:none;fill-opacity:1;stroke:#009500;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4173-35"
width="425.19684"
height="53.149609"
x="53.149605"
y="148.81889" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="60.171993"
y="162.72299"
id="text4443-9-6-6"><tspan
sodipodi:role="line"
id="tspan4445-2-75-2"
x="60.171993"
y="162.72299"
style="font-size:12.5px;line-height:1.25">#window mainbox message</tspan></text>
<g
id="g4403"
transform="translate(16.738798,-8.6793767)">
<text
id="text4258-1-9"
y="194.98009"
x="220.6938"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="194.98009"
x="220.6938"
id="tspan4260-2-12"
sodipodi:role="line">textbox</tspan></text>
<rect
y="175.21481"
x="54.127342"
height="28.346453"
width="389.76379"
id="rect4300-9-7"
style="fill:none;fill-opacity:1;stroke:#950006;stroke-width:1.98821568;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4408-3"
transform="translate(6.5112369,24.471404)">
<text
id="text4258-1-6-6"
y="266.72287"
x="101.68279"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="266.72287"
x="101.68279"
id="tspan4260-2-1-0"
sodipodi:role="line">Element</tspan></text>
<rect
y="248.08116"
x="64.000687"
height="28.346462"
width="141.73228"
id="rect4368-6"
style="fill:none;fill-opacity:1;stroke:#ffc602;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4408-2"
transform="translate(6.5112369,60.457378)">
<text
id="text4258-1-6-61"
y="266.72287"
x="101.68279"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="266.72287"
x="101.68279"
id="tspan4260-2-1-8"
sodipodi:role="line">Element</tspan></text>
<rect
y="248.08116"
x="64.000687"
height="28.346462"
width="141.73228"
id="rect4368-7"
style="fill:none;fill-opacity:1;stroke:#ffc602;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4408-9"
transform="translate(183.85932,-10.988865)">
<text
id="text4258-1-6-2"
y="266.72287"
x="101.68279"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="266.72287"
x="101.68279"
id="tspan4260-2-1-02"
sodipodi:role="line">Element</tspan></text>
<rect
y="248.08116"
x="64.000687"
height="28.346462"
width="141.73228"
id="rect4368-3"
style="fill:none;fill-opacity:1;stroke:#ffc602;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4408-3-7"
transform="translate(183.85932,24.162135)">
<text
id="text4258-1-6-6-5"
y="266.72287"
x="101.68279"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="266.72287"
x="101.68279"
id="tspan4260-2-1-0-9"
sodipodi:role="line">Element</tspan></text>
<rect
y="248.08116"
x="64.000687"
height="28.346462"
width="141.73228"
id="rect4368-6-2"
style="fill:none;fill-opacity:1;stroke:#ffc602;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g4408-2-2"
transform="translate(183.85932,60.148105)">
<text
id="text4258-1-6-61-8"
y="266.72287"
x="101.68279"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0000c2;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:15px;line-height:1.25;fill:#0000c2;fill-opacity:1"
y="266.72287"
x="101.68279"
id="tspan4260-2-1-8-9"
sodipodi:role="line">Element</tspan></text>
<rect
y="248.08116"
x="64.000687"
height="28.346462"
width="141.73228"
id="rect4368-7-7"
style="fill:none;fill-opacity:1;stroke:#ffc602;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1,95 @@
## Transparency within rofi
> The images in this guide are outdated, but the principals still hold.
**Rofi** window is build up by first drawing the background, and then each
widget above it, with the correct transparency factor.
Remember the general widget structure:
![structure](structure.svg)
This means if you set every widget to be 30% transparent on a white background: it will look like:
![images](rofi-transp.png)
The transparency applies one on top of the other, so while they all are 30%, in
the end it will be less transparent.
> Try it yourself
```bash
rofi -theme-str '@theme "/dev/null" window { background-color: white; }* { padding:5; background-color: rgba(20,20,20,0.5);}' -show run
```
This can sometimes be difficult when creating themes with a nice transparent
background.
The trick to make this work nicely is the following.
Specify fully transparent background on the highest level.
```css
* {
background: transparent;
}
```
Then set the background on the window box.
```css
window {
background: #cc1c1c1c;
}
```
Now if you only set the background on widgets you want differently colored, it
nicely works out.
## Transparency on the window
This determines how transparency on the window is handled.
This is set the be `transparency` option on the `window` widget.
The option takes a string. There are basically 4 options:
### No transparency or "real"
The background of the window is black and fully transparent, and everything is drawn on top of this.
This means that if you have a composite manager (ARGB window), you get a fully transparent
background, otherwise fully black.
This is the preferred option if you have a composite manager running.
![rofi real](rofi-real.png)
This image is actually partially transparent (won't show here clearly as block
background is white.)
### Fake transparency or "screenshot"
This tries to emulate a transparent window by taking a screenshot of the window
before showing and then drawing everything on top of this. While this is not an
ideal solution (it won't update if something changes in the background) it is
often a very usable facsimile.
![rofi fake](rofi-fake.png)
> Note: It can get very slow, especially on high resolution (4k) monitors.
### Background transparency or "background"
This uses the background image (the root window image). This is, in my opinion,
mostly useful when used fullscreen.
![rofi background](rofi-background2.png)
![rofi background2](rofi-background.png)
### Picture
If instead of one of the above option, you specify a path to a png file this is
used as background image. This can create a theme where you use paper as
background.
![rofi paper](rofi-paper.png)

View file

@ -14,3 +14,5 @@ configuration {
directories-first: true; directories-first: true;
} }
} }
@theme "default"

View file

@ -1,10 +1,12 @@
ronn = find_program('ronn', required: false) gomd2man = find_program('go-md2man', required: false)
if ronn.found() if gomd2man.found()
run_target('update-manpage', run_target('update-manpage',
command: [ ronn, '--roff', files( command: [ 'meson_build_manpages.sh', files(
'rofi.1.markdown', 'rofi.1.markdown',
'rofi-theme-selector.1.markdown', 'rofi-theme-selector.1.markdown',
'rofi-theme.5.markdown', 'rofi-theme.5.markdown',
'rofi-script.5.markdown',
'rofi-sensible-terminal.1.markdown'
)] )]
) )
endif endif

12
doc/meson_build_manpages.sh Executable file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
## Did not get this working in meson directly.
## not via generator or custom_target.
pushd "${MESON_BUILD_ROOT}"
for a in $@
do
go-md2man -in $a -out ${a%.markdown}
done

View file

@ -1141,6 +1141,7 @@ The offset of the window to the anchor point, allowing you to push the window le
.IP \(bu 2 .IP \(bu 2
\fBhighlight\fP: text style {color}. \fBhighlight\fP: text style {color}.
color is optional, multiple highlight styles can be added like: bold underline italic #000000; color is optional, multiple highlight styles can be added like: bold underline italic #000000;
This option is only available on the \fB\fCelement\-text\fR widget.
.IP \(bu 2 .IP \(bu 2
\fBwidth\fP: override the desired width for the textbox. \fBwidth\fP: override the desired width for the textbox.
.IP \(bu 2 .IP \(bu 2

View file

@ -695,6 +695,7 @@ The following properties are currently supported:
* **text-color**: the text color to use. * **text-color**: the text color to use.
* **highlight**: text style {color}. * **highlight**: text style {color}.
color is optional, multiple highlight styles can be added like: bold underline italic #000000; color is optional, multiple highlight styles can be added like: bold underline italic #000000;
This option is only available on the `element-text` widget.
* **width**: override the desired width for the textbox. * **width**: override the desired width for the textbox.
* **content**: Set the displayed text (String). * **content**: Set the displayed text (String).
* **placeholder**: Set the displayed text (String) when nothing is entered. * **placeholder**: Set the displayed text (String) when nothing is entered.

View file

@ -45,7 +45,7 @@ The website for \fB\fCdmenu\fR can be found here
\[la]http://tools.suckless.org/dmenu/\[ra]\&. \[la]http://tools.suckless.org/dmenu/\[ra]\&.
.PP .PP
\fBrofi\fP does not aim to be 100% compatible with \fB\fCdmenu\fR\&. There are simply too many different flavors of \fB\fCdmenu\fR\&. \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). Besides, \fBrofi\fP offers some extended features (like multi\-select, highlighting, message bar, extra key bindings).
@ -72,7 +72,7 @@ There are currently three methods of setting configuration options (evaluated in
.RS .RS
.IP \(bu 2 .IP \(bu 2
System configuration file (for example \fB\fC/etc/rofi.rasi\fR). System configuration file (for example \fB\fC/etc/rofi.rasi\fR).
It first checks XDG\_CONFIG\_DIRS and then SYSCONFDIR (that is passed at compile time). It first checks \fB\fCXDG\_CONFIG\_DIRS\fR, and then \fB\fCSYSCONFDIR\fR (that is passed at compile time).
It loads the first config file it finds, it does not merge multiple system configuration files. It loads the first config file it finds, it does not merge multiple system configuration files.
.IP \(bu 2 .IP \(bu 2
Rasi theme file: The new \fItheme\fP format can be used to set configuration values. Rasi theme file: The new \fItheme\fP format can be used to set configuration values.
@ -82,7 +82,7 @@ Command\-line options: Arguments passed to \fBrofi\fP\&.
.RE .RE
.PP .PP
To get a template config file run: \fB\fCrofi \-dump\-config > config.rasi\fR To get a template config file, run: \fB\fCrofi \-dump\-config > config.rasi\fR
.PP .PP
This will contain (commented) all current configuration options, modified options are uncommented. This will contain (commented) all current configuration options, modified options are uncommented.
@ -105,10 +105,10 @@ lists
.RE .RE
.PP .PP
For the syntax of these options see the \fBrofi\-theme(5)\fP manpage. For the syntax of these options, see the \fBrofi\-theme(5)\fP manpage.
.PP .PP
For use on the commandline, Boolean options have a non\-default command\-line For use on the command line, Boolean options have a non\-default command\-line
syntax. Example to enable option X: syntax. Example to enable option X:
.PP .PP
@ -182,7 +182,7 @@ Specify the number of threads \fBrofi\fP should use:
.IP \(bu 2 .IP \(bu 2
.PP .PP
2..N: Specify the maximum number of threads to use in the thread pool. 2..n: Specify the maximum number of threads to use in the thread pool.
.PP .PP
Default: Autodetect Default: Autodetect
@ -289,8 +289,8 @@ rofi \-modi "window,run,ssh,Workspaces:i3\_switch\_workspaces.sh" \-show Workspa
.RE .RE
.PP .PP
Notes: The i3 window manager does not like commas in the command when specifying an exec command. Notes: The i3 window manager dislikes commas in the command when specifying an exec command.
For that case '#' can be used as an separator. For that case, \fB\fC#\fR can be used as a separator.
.PP .PP
\fBTIP\fP: The name is allowed to contain spaces: \fBTIP\fP: The name is allowed to contain spaces:
@ -308,7 +308,7 @@ rofi \-modi "My File Browser:fb.sh" \-show "My File Browser"
\fB\fC\-case\-sensitive\fR \fB\fC\-case\-sensitive\fR
.PP .PP
Start in case sensitive mode. Start in case\-sensitive mode.
This option can be changed at run\-time using the \fB\fC\-kb\-toggle\-case\-sensitivity\fR key binding. This option can be changed at run\-time using the \fB\fC\-kb\-toggle\-case\-sensitivity\fR key binding.
.PP .PP
@ -345,9 +345,9 @@ Select the scrolling method. 0: Per page, 1: continuous.
\fB\fC\-normalize\-match\fR \fB\fC\-normalize\-match\fR
.PP .PP
Normalize the string before matching, so o will match ö, and é matches e. Normalize the string before matching, so \fB\fCo\fR will match \fB\fCö\fR, and \fB\fCé\fR matches \fB\fCe\fR\&.
This is not a perfect implementation, but works. .br
For now it disabled highlighting of the matched part. This is not a perfect implementation, but works. For now, it disables highlighting of the matched part.
.PP .PP
\fB\fC\-no\-lazy\-grab\fR \fB\fC\-no\-lazy\-grab\fR
@ -411,7 +411,7 @@ Make rofi steal focus on launch and restore close to window that held it when la
.PP .PP
Specify the matching algorithm used. Specify the matching algorithm used.
Current the following methods are supported. Currently, the following methods are supported:
.RS .RS
.IP \(bu 2 .IP \(bu 2
@ -466,7 +466,7 @@ The different fields are:
.IP \(bu 2 .IP \(bu 2
.PP .PP
\fBall\fP: all of the above \fBall\fP: all the above
.PP .PP
Default: \fIname,generic,exec,categories,keywords\fP Default: \fIname,generic,exec,categories,keywords\fP
@ -543,7 +543,7 @@ The different fields are:
.IP \(bu 2 .IP \(bu 2
.PP .PP
\fBall\fP: all of the above \fBall\fP: all the above
.PP .PP
Default: \fIall\fP Default: \fIall\fP
@ -553,7 +553,7 @@ Default: \fIall\fP
\fB\fC\-matching\-negate\-char\fR \fIchar\fP \fB\fC\-matching\-negate\-char\fR \fIchar\fP
.PP .PP
Set the character used to negate the query (i.e. if it does \fBnot\fP match the next keyword ). Set the character used to negate the query (i.e. if it does \fBnot\fP match the next keyword).
Set to '\\x0' to disable. Set to '\\x0' to disable.
.PP .PP
@ -569,8 +569,8 @@ Default: '\-'
.PP .PP
\fBIMPORTANT:\fP \fBIMPORTANT:\fP
In newer \fBrofi\fP releases, all the theming options have been moved into the new theme format. They are no longer normal In newer \fBrofi\fP releases, all the theming options have been moved into the new theme format. They are no longer normal
\fBrofi\fP options that can be passed directly on the commandline (there are too many). \fBrofi\fP options that can be passed directly on the command line (there are too many).
Small snippets can be passed on the commandline: \fB\fCrofi \-theme\-str 'window {width: 50%;}'\fR to override a single Small snippets can be passed on the command line: \fB\fCrofi \-theme\-str 'window {width: 50%;}'\fR to override a single
setting. They are merged into the current theme. setting. They are merged into the current theme.
They can also be appended at the end of the \fBrofi\fP config file to override parts of the theme. They can also be appended at the end of the \fBrofi\fP config file to override parts of the theme.
@ -608,7 +608,7 @@ Keep a fixed number of visible lines (See the \fB\fC\-lines\fR option.)
\fB\fC\-sidebar\-mode\fR \fB\fC\-sidebar\-mode\fR
.PP .PP
Open in sidebar\-mode. In this mode a list of all enabled modes is shown at the bottom. Open in sidebar\-mode. In this mode, a list of all enabled modes is shown at the bottom.
(See \fB\fC\-modi\fR option) (See \fB\fC\-modi\fR option)
To show sidebar, use: To show sidebar, use:
@ -673,7 +673,7 @@ detection). Negative numbers are handled differently:
.IP \(bu 2 .IP \(bu 2
\fB\-2\fP: the currently focused window (that is, \fBrofi\fP will be displayed on top of the focused window). \fB\-2\fP: the currently focused window (that is, \fBrofi\fP will be displayed on top of the focused window).
.IP \(bu 2 .IP \(bu 2
\fB\-3\fP: Position at mouse (overrides the location setting to get normal context menu \fB\-3\fP: Position of mouse (overrides the location setting to get normal context menu
behavior.) behavior.)
.IP \(bu 2 .IP \(bu 2
\fB\-4\fP: the monitor with the focused window. \fB\-4\fP: the monitor with the focused window.
@ -715,7 +715,7 @@ rofi \-theme\-str '#window { fullscreen: true; }'
.PP .PP
This option can be specified multiple times. This option can be specified multiple times.
This is now the method to tweak the theme via the commandline. This is now the method to tweak the theme via the command line.
.PP .PP
\fB\fC\-dpi\fR \fInumber\fP \fB\fC\-dpi\fR \fInumber\fP
@ -779,7 +779,7 @@ Default: \fIssh\fP
\fB\fC\-ssh\-command\fR \fIcmd\fP \fB\fC\-ssh\-command\fR \fIcmd\fP
.PP .PP
Set the command to execute when starting a ssh session. Set the command to execute when starting an ssh session.
The pattern \fI{host}\fP is replaced by the selected ssh entry. The pattern \fI{host}\fP is replaced by the selected ssh entry.
.PP .PP
@ -832,7 +832,7 @@ Default: \fI{terminal} \-e {cmd}\fP
\fB\fC\-run\-list\-command\fR \fIcmd\fP \fB\fC\-run\-list\-command\fR \fIcmd\fP
.PP .PP
If set, use an external tool to generate list of executable commands. Uses \fB\fCrun\-command\fR\&. If set, use an external tool to generate a list of executable commands. Uses \fB\fCrun\-command\fR\&.
.PP .PP
Default: \fI{cmd}\fP Default: \fI{cmd}\fP
@ -866,7 +866,8 @@ Format what is being displayed for windows.
.PP .PP
\fIlen\fP: maximum field length (0 for auto\-size). If length and window \fIwidth\fP are negative, field length is \fIwidth \- len\fP\&. \fIlen\fP: maximum field length (0 for auto\-size). If length and window \fIwidth\fP are negative, field length is \fIwidth \- len\fP\&.
if length is positive, the entry will be truncated or padded to fill that length. .br
If length is positive, the entry will be truncated or padded to fill that length.
.PP .PP
default: {w} {c} {t} default: {w} {c} {t}
@ -875,7 +876,7 @@ default: {w} {c} {t}
\fB\fC\-window\-command\fR \fIcmd\fP \fB\fC\-window\-command\fR \fIcmd\fP
.PP .PP
Set command to execute on selected window for a alt action (\fB\fC\-kb\-accept\-alt\fR). Set command to execute on selected window for an alt action (\fB\fC\-kb\-accept\-alt\fR).
See \fIPATTERN\fP\&. See \fIPATTERN\fP\&.
.PP .PP
@ -922,8 +923,8 @@ rofi \-show combi \-combi\-modi "window,run,ssh" \-modi combi
.RE .RE
.PP .PP
\fBNOTE\fP: The i3 window manager does not like commas in the command when specifying an exec command. \fBNOTE\fP: The i3 window manager dislikes commas in the command when specifying an exec command.
For that case '#' can be used as a separator. For that case, \fB\fC#\fR can be used as a separator.
.SS History and Sorting .SS History and Sorting
.PP .PP
@ -945,7 +946,7 @@ This setting can be changed at runtime (see \fB\fC\-kb\-toggle\-sort\fR).
\fB\fC\-sorting\-method\fR 'method' to specify the sorting method. \fB\fC\-sorting\-method\fR 'method' to specify the sorting method.
.PP .PP
There are 2 sorting method: There are 2 sorting methods:
.RS .RS
.IP \(bu 2 .IP \(bu 2
@ -1098,7 +1099,7 @@ Select first line that matches the given string
.PP .PP
Add a message line below the filter entry box. Supports Pango markup. Add a message line below the filter entry box. Supports Pango markup.
For more information on supported markup see here For more information on supported markup, see here
\[la]https://developer.gnome.org/pygtk/stable/pango-markup-language.html\[ra] \[la]https://developer.gnome.org/pygtk/stable/pango-markup-language.html\[ra]
.PP .PP
@ -1171,7 +1172,7 @@ Position \fBrofi\fP over the window with the given X11 window ID.
\fB\fC\-keep\-right\fR \fB\fC\-keep\-right\fR
.PP .PP
Set ellipsize mode to start. So end of string is visible. Set ellipsize mode to start. So, the end of the string is visible.
.SS Message dialog .SS Message dialog
.PP .PP
@ -1261,7 +1262,7 @@ configuration {
\fB\fC\-no\-click\-to\-exit\fR \fB\fC\-no\-click\-to\-exit\fR
.PP .PP
Click the mouse outside of the \fBrofi\fP window to exit. Click the mouse outside the \fBrofi\fP window to exit.
.PP .PP
Default: \fIenabled\fP Default: \fIenabled\fP
@ -1287,7 +1288,7 @@ To launch commands (for example, when using the ssh launcher), the user can ente
.SH DMENU REPLACEMENT .SH DMENU REPLACEMENT
.PP .PP
If \fB\fCargv[0]\fR (calling command) is dmenu, \fBrofi\fP will start in dmenu mode. If \fB\fCargv[0]\fR (calling command) is dmenu, \fBrofi\fP will start in dmenu mode.
This way it can be used as a drop\-in replacement for dmenu. Just copy or symlink \fBrofi\fP to dmenu in \fB\fC$PATH\fR\&. This way, it can be used as a drop\-in replacement for dmenu. Just copy or symlink \fBrofi\fP to dmenu in \fB\fC$PATH\fR\&.
.PP .PP
.RS .RS
@ -1308,63 +1309,63 @@ Please see \fBrofi\-theme(5)\fP manpage for more information on theming.
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-v, Insert\fR: Paste from clipboard \fB\fCControl\-v, Insert\fR: Paste from clipboard
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Shift\-v, Shift\-Insert\fR: Paste primary selection \fB\fCControl\-Shift\-v, Shift\-Insert\fR: Paste primary selection
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-u\fR: Clear the line \fB\fCControl\-u\fR: Clear the line
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-a\fR: Beginning of line \fB\fCControl\-a\fR: Beginning of line
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-e\fR: End of line \fB\fCControl\-e\fR: End of line
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-f, Right\fR: Forward one character \fB\fCControl\-f, Right\fR: Forward one character
.IP \(bu 2 .IP \(bu 2
\fB\fCAlt\-f, Ctrl\-Right\fR: Forward one word \fB\fCAlt\-f, Control\-Right\fR: Forward one word
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-b, Left\fR: Back one character \fB\fCControl\-b, Left\fR: Back one character
.IP \(bu 2 .IP \(bu 2
\fB\fCAlt\-b, Ctrl\-Left\fR: Back one word \fB\fCAlt\-b, Control\-Left\fR: Back one word
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-d, Delete\fR: Delete character \fB\fCControl\-d, Delete\fR: Delete character
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Alt\-d\fR: Delete word \fB\fCControl\-Alt\-d\fR: Delete word
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-h, Backspace, Shift\-Backspace\fR: Backspace (delete previous character) \fB\fCControl\-h, Backspace, Shift\-Backspace\fR: Backspace (delete previous character)
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Alt\-h\fR: Delete previous word \fB\fCControl\-Alt\-h\fR: Delete previous word
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-j,Ctrl\-m,Enter\fR: Accept entry \fB\fCControl\-j,Control\-m,Enter\fR: Accept entry
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-n,Down\fR: Select next entry \fB\fCControl\-n,Down\fR: Select next entry
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-p,Up\fR: Select previous entry \fB\fCControl\-p,Up\fR: Select previous entry
.IP \(bu 2 .IP \(bu 2
\fB\fCPage Up\fR: Go to previous page \fB\fCPage Up\fR: Go to previous page
.IP \(bu 2 .IP \(bu 2
\fB\fCPage Down\fR: Go to next page \fB\fCPage Down\fR: Go to next page
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Page Up\fR: Go to previous column \fB\fCControl\-Page Up\fR: Go to previous column
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Page Down\fR: Go to next column \fB\fCControl\-Page Down\fR: Go to next column
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Enter\fR: Use entered text as a command (in \fB\fCssh/run modi\fR) \fB\fCControl\-Enter\fR: Use entered text as a command (in \fB\fCssh/run modi\fR)
.IP \(bu 2 .IP \(bu 2
\fB\fCShift\-Enter\fR: Launch the application in a terminal (in run mode) \fB\fCShift\-Enter\fR: Launch the application in a terminal (in run mode)
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Shift\-Enter\fR: As Ctrl\-Enter and run the command in terminal (in run mode) \fB\fCControl\-Shift\-Enter\fR: As Control\-Enter and run the command in terminal (in run mode)
.IP \(bu 2 .IP \(bu 2
\fB\fCShift\-Enter\fR: Return the selected entry and move to the next item while keeping \fBrofi\fP open. (in dmenu) \fB\fCShift\-Enter\fR: Return the selected entry and move to the next item while keeping \fBrofi\fP open. (in dmenu)
.IP \(bu 2 .IP \(bu 2
\fB\fCShift\-Right\fR: Switch to the next mode. The list can be customized with the \fB\fC\-switchers\fR argument. \fB\fCShift\-Right\fR: Switch to the next mode. The list can be customized with the \fB\fC\-modi\fR argument.
.IP \(bu 2 .IP \(bu 2
\fB\fCShift\-Left\fR: Switch to the previous mode. The list can be customized with the \fB\fC\-switchers\fR argument. \fB\fCShift\-Left\fR: Switch to the previous mode. The list can be customized with the \fB\fC\-modi\fR argument.
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Tab\fR: Switch to the next mode. The list can be customized with the \fB\fC\-switchers\fR argument. \fB\fCControl\-Tab\fR: Switch to the next mode. The list can be customized with the \fB\fC\-modi\fR argument.
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-Shift\-Tab\fR: Switch to the previous mode. The list can be customized with the \fB\fC\-switchers\fR argument. \fB\fCControl\-Shift\-Tab\fR: Switch to the previous mode. The list can be customized with the \fB\fC\-modi\fR argument.
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-space\fR: Set selected item as input text. \fB\fCControl\-space\fR: Set selected item as input text.
.IP \(bu 2 .IP \(bu 2
\fB\fCShift\-Del\fR: Delete entry from history. \fB\fCShift\-Del\fR: Delete entry from history.
.IP \(bu 2 .IP \(bu 2
@ -1374,14 +1375,19 @@ Please see \fBrofi\-theme(5)\fP manpage for more information on theming.
.IP \(bu 2 .IP \(bu 2
\fB\fCAlt\-Shift\-S\fR: Take a screenshot and store it in the Pictures directory. \fB\fCAlt\-Shift\-S\fR: Take a screenshot and store it in the Pictures directory.
.IP \(bu 2 .IP \(bu 2
\fB\fCCtrl\-l\fR: File complete for run dialog. \fB\fCControl\-l\fR: File complete for run dialog.
.RE .RE
.PP .PP
To get a full list of key bindings on the commandline, see \fB\fCrofi \-h\fR\&. This list might not be complete, to get a full list of all key bindings
The options starting with \fB\fC\-kb\fR are keybindings. supported in your rofi, see \fB\fCrofi \-h\fR\&. The options starting with \fB\fC\-kb\fR are keybindings.
Key bindings can be modified using the configuration systems.
.PP
Key bindings can be modified using the configuration systems. Multiple keys can be bound
to one action by comma separating them. For example \fB\fC\-kb\-primary\-paste "Conctrol+v,Insert"\fR
.PP
To get a searchable list of key bindings, run \fB\fCrofi \-show keys\fR\&. To get a searchable list of key bindings, run \fB\fCrofi \-show keys\fR\&.
.PP .PP
@ -1432,11 +1438,11 @@ When pressing the \fB\fCmode\-complete\fR binding (\fB\fCControl\-l\fR), you can
passing a file as argument if specified in the desktop file. passing a file as argument if specified in the desktop file.
.PP .PP
The DRUN mode tries to follows the XDG Desktop Entry The DRUN mode tries to follow the XDG Desktop Entry
Specification Specification
\[la]https://freedesktop.org/wiki/Specifications/desktop-entry-spec/\[ra] and should be compatible with \[la]https://freedesktop.org/wiki/Specifications/desktop-entry-spec/\[ra] and should be compatible with
applications using this standard. Some application create invalid desktop files, \fBrofi\fP will discard these entries. applications using this standard. Some applications create invalid desktop files, \fBrofi\fP will discard these entries.
See de debugging section how to get more information from the DRUN mode, this will print why desktop files are See the debugging section for more info on DRUN mode, this will print why desktop files are
discarded. discarded.
.PP .PP
@ -1660,14 +1666,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\fBrofi\fP support can be obtained: \fBrofi\fP support can be obtained:
* GitHub Discussions * GitHub Discussions
\[la]https://github.com/davatorium/rofi/discussions\[ra] \[la]https://github.com/davatorium/rofi/discussions\[ra]
* Forum (reddit) * Forum (Reddit)
\[la]https://reddit.com/r/qtools//\[ra] \[la]https://reddit.com/r/qtools//\[ra]
* IRC * IRC
\[la]irc://irc.libera.chat:6697/#rofi\[ra] (#rofi on irc.libera.chat), \[la]irc://irc.libera.chat:6697/#rofi\[ra] (#rofi on irc.libera.chat),
.SH DEBUGGING .SH DEBUGGING
.PP .PP
To debug it is smart to first try disabling your custom configuration: To debug, it is smart to first try disabling your custom configuration:
\fB\fC\-no\-config\fR \fB\fC\-no\-config\fR
.PP .PP
@ -1685,7 +1691,7 @@ Disables the loading of plugins.
.PP .PP
To further debug the plugin, you can get a trace with (lots of) debug information. This debug output can be enabled for To further debug the plugin, you can get a trace with (lots of) debug information. This debug output can be enabled for
multiple parts in rofi using the glib debug framework. Debug domains can be enabled by setting the G\_MESSAGES\_DEBUG multiple parts in rofi using the glib debug framework. Debug domains can be enabled by setting the G\_MESSAGES\_DEBUG
environment variable. At creation of this page the following debug domains exists: environment variable. At the time of creation of this page, the following debug domains exist:
.RS .RS
.IP \(bu 2 .IP \(bu 2
@ -1734,7 +1740,7 @@ The output of this can provide useful information when writing an issue.
.PP .PP
More information (possibly outdated) see this More information (possibly outdated) see this
\[la]https://github.com/DaveDavenport/rofi/wiki/Debugging Rofi\[ra] wiki entry. \[la]https://github.com/DaveDavenport/rofi/wiki/Debugging%20Rofi\[ra] wiki entry.
.SH ISSUE TRACKER .SH ISSUE TRACKER
.PP .PP

View file

@ -37,7 +37,7 @@ To show the `run` dialog:
The website for `dmenu` can be found [here](http://tools.suckless.org/dmenu/). The website for `dmenu` can be found [here](http://tools.suckless.org/dmenu/).
**rofi** does not aim to be 100% compatible with `dmenu`. There are simply too many different flavors of `dmenu`. **rofi** does not aim to be 100% compatible with `dmenu`. There are simply too many flavors of `dmenu`.
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, **rofi** offers some extended features (like multi-select, highlighting, message bar, extra key bindings). Besides, **rofi** offers some extended features (like multi-select, highlighting, message bar, extra key bindings).
@ -54,12 +54,12 @@ Markup support can be enabled, see CONFIGURATION options.
There are currently three methods of setting configuration options (evaluated in order below): There are currently three methods of setting configuration options (evaluated in order below):
* System configuration file (for example `/etc/rofi.rasi`). * System configuration file (for example `/etc/rofi.rasi`).
It first checks XDG\_CONFIG\_DIRS and then SYSCONFDIR (that is passed at compile time). It first checks `XDG_CONFIG_DIRS`, and then `SYSCONFDIR` (that is passed at compile time).
It loads the first config file it finds, it does not merge multiple system configuration files. It loads the first config file it finds, it does not merge multiple system configuration files.
* Rasi theme file: The new *theme* format can be used to set configuration values. * Rasi theme file: The new *theme* format can be used to set configuration values.
* Command-line options: Arguments passed to **rofi**. * Command-line options: Arguments passed to **rofi**.
To get a template config file run: `rofi -dump-config > config.rasi` To get a template config file, run: `rofi -dump-config > config.rasi`
This will contain (commented) all current configuration options, modified options are uncommented. This will contain (commented) all current configuration options, modified options are uncommented.
@ -71,9 +71,9 @@ The configuration system supports the following types:
* boolean * boolean
* lists * lists
For the syntax of these options see the **rofi-theme(5)** manpage. For the syntax of these options, see the **rofi-theme(5)** manpage.
For use on the commandline, Boolean options have a non-default command-line For use on the command line, Boolean options have a non-default command-line
syntax. Example to enable option X: syntax. Example to enable option X:
-X -X
@ -114,7 +114,7 @@ Specify the number of threads **rofi** should use:
* 0: Autodetect the number of supported hardware threads. * 0: Autodetect the number of supported hardware threads.
* 1: Disable threading * 1: Disable threading
* 2..N: Specify the maximum number of threads to use in the thread pool. * 2..n: Specify the maximum number of threads to use in the thread pool.
Default: Autodetect Default: Autodetect
@ -163,8 +163,8 @@ Example: Have a mode called 'Workspaces' using the `i3_switch_workspaces.sh` scr
rofi -modi "window,run,ssh,Workspaces:i3_switch_workspaces.sh" -show Workspaces rofi -modi "window,run,ssh,Workspaces:i3_switch_workspaces.sh" -show Workspaces
Notes: The i3 window manager does not like commas in the command when specifying an exec command. Notes: The i3 window manager dislikes commas in the command when specifying an exec command.
For that case '#' can be used as an separator. For that case, `#` can be used as a separator.
**TIP**: The name is allowed to contain spaces: **TIP**: The name is allowed to contain spaces:
@ -172,7 +172,7 @@ For that case '#' can be used as an separator.
`-case-sensitive` `-case-sensitive`
Start in case sensitive mode. Start in case-sensitive mode.
This option can be changed at run-time using the `-kb-toggle-case-sensitivity` key binding. This option can be changed at run-time using the `-kb-toggle-case-sensitivity` key binding.
`-cycle` `-cycle`
@ -197,9 +197,8 @@ Select the scrolling method. 0: Per page, 1: continuous.
`-normalize-match` `-normalize-match`
Normalize the string before matching, so o will match ö, and é matches e. Normalize the string before matching, so `o` will match `ö`, and `é` matches `e`.
This is not a perfect implementation, but works. This is not a perfect implementation, but works. For now, it disables highlighting of the matched part.
For now it disabled highlighting of the matched part.
`-no-lazy-grab` `-no-lazy-grab`
@ -244,7 +243,7 @@ Make rofi steal focus on launch and restore close to window that held it when la
`-matching` *method* `-matching` *method*
Specify the matching algorithm used. Specify the matching algorithm used.
Current the following methods are supported. Currently, the following methods are supported:
* **normal**: match the int string * **normal**: match the int string
* **regex**: match a regex input * **regex**: match a regex input
@ -274,7 +273,7 @@ The different fields are:
* **exec**: the application's executable * **exec**: the application's executable
* **categories**: the application's categories * **categories**: the application's categories
* **comment**: the application comment * **comment**: the application comment
* **all**: all of the above * **all**: all the above
Default: *name,generic,exec,categories,keywords* Default: *name,generic,exec,categories,keywords*
@ -310,13 +309,13 @@ The different fields are:
* **role**: window's role * **role**: window's role
* **name**: window's name * **name**: window's name
* **desktop**: window's current desktop * **desktop**: window's current desktop
* **all**: all of the above * **all**: all the above
Default: *all* Default: *all*
`-matching-negate-char` *char* `-matching-negate-char` *char*
Set the character used to negate the query (i.e. if it does **not** match the next keyword ). Set the character used to negate the query (i.e. if it does **not** match the next keyword).
Set to '\x0' to disable. Set to '\x0' to disable.
Default: '-' Default: '-'
@ -326,8 +325,8 @@ Set to '\x0' to disable.
**IMPORTANT:** **IMPORTANT:**
In newer **rofi** releases, all the theming options have been moved into the new theme format. They are no longer normal In newer **rofi** releases, all the theming options have been moved into the new theme format. They are no longer normal
**rofi** options that can be passed directly on the commandline (there are too many). **rofi** options that can be passed directly on the command line (there are too many).
Small snippets can be passed on the commandline: `rofi -theme-str 'window {width: 50%;}'` to override a single Small snippets can be passed on the command line: `rofi -theme-str 'window {width: 50%;}'` to override a single
setting. They are merged into the current theme. setting. They are merged into the current theme.
They can also be appended at the end of the **rofi** config file to override parts of the theme. They can also be appended at the end of the **rofi** config file to override parts of the theme.
@ -350,7 +349,7 @@ Keep a fixed number of visible lines (See the `-lines` option.)
`-sidebar-mode` `-sidebar-mode`
Open in sidebar-mode. In this mode a list of all enabled modes is shown at the bottom. Open in sidebar-mode. In this mode, a list of all enabled modes is shown at the bottom.
(See `-modi` option) (See `-modi` option)
To show sidebar, use: To show sidebar, use:
@ -386,7 +385,7 @@ detection). Negative numbers are handled differently:
* **-1**: the currently focused monitor. * **-1**: the currently focused monitor.
* **-2**: the currently focused window (that is, **rofi** will be displayed on top of the focused window). * **-2**: the currently focused window (that is, **rofi** will be displayed on top of the focused window).
* **-3**: Position at mouse (overrides the location setting to get normal context menu * **-3**: Position of mouse (overrides the location setting to get normal context menu
behavior.) behavior.)
* **-4**: the monitor with the focused window. * **-4**: the monitor with the focused window.
* **-5**: the monitor that shows the mouse pointer. * **-5**: the monitor that shows the mouse pointer.
@ -409,7 +408,7 @@ For example:
rofi -theme-str '#window { fullscreen: true; }' rofi -theme-str '#window { fullscreen: true; }'
This option can be specified multiple times. This option can be specified multiple times.
This is now the method to tweak the theme via the commandline. This is now the method to tweak the theme via the command line.
`-dpi` *number* `-dpi` *number*
@ -448,7 +447,7 @@ Default: *ssh*
`-ssh-command` *cmd* `-ssh-command` *cmd*
Set the command to execute when starting a ssh session. Set the command to execute when starting an ssh session.
The pattern *{host}* is replaced by the selected ssh entry. The pattern *{host}* is replaced by the selected ssh entry.
Pattern: *{ssh-client}* Pattern: *{ssh-client}*
@ -486,7 +485,7 @@ Default: *{terminal} -e {cmd}*
`-run-list-command` *cmd* `-run-list-command` *cmd*
If set, use an external tool to generate list of executable commands. Uses `run-command`. If set, use an external tool to generate a list of executable commands. Uses `run-command`.
Default: *{cmd}* Default: *{cmd}*
@ -506,15 +505,15 @@ Format what is being displayed for windows.
* **r**: role * **r**: role
* **c**: class * **c**: class
*len*: maximum field length (0 for auto-size). If length and window *width* are negative, field length is *width - len*. *len*: maximum field length (0 for auto-size). If length and window *width* are negative, field length is *width - len*.
if length is positive, the entry will be truncated or padded to fill that length. If length is positive, the entry will be truncated or padded to fill that length.
default: {w} {c} {t} default: {w} {c} {t}
`-window-command` *cmd* `-window-command` *cmd*
Set command to execute on selected window for a alt action (`-kb-accept-alt`). Set command to execute on selected window for an alt action (`-kb-accept-alt`).
See *PATTERN*. See *PATTERN*.
Default: *"wmctrl -i -R {window}"* Default: *"wmctrl -i -R {window}"*
@ -545,8 +544,8 @@ To get one merge view, of `window`,`run`, and `ssh`:
rofi -show combi -combi-modi "window,run,ssh" -modi combi rofi -show combi -combi-modi "window,run,ssh" -modi combi
**NOTE**: The i3 window manager does not like commas in the command when specifying an exec command. **NOTE**: The i3 window manager dislikes commas in the command when specifying an exec command.
For that case '#' can be used as a separator. For that case, `#` can be used as a separator.
### History and Sorting ### History and Sorting
@ -563,7 +562,7 @@ This setting can be changed at runtime (see `-kb-toggle-sort`).
`-sorting-method` 'method' to specify the sorting method. `-sorting-method` 'method' to specify the sorting method.
There are 2 sorting method: There are 2 sorting methods:
* levenshtein (Default) * levenshtein (Default)
* fzf sorting. * fzf sorting.
@ -646,7 +645,7 @@ Select first line that matches the given string
`-mesg` *string* `-mesg` *string*
Add a message line below the filter entry box. Supports Pango markup. 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://developer.gnome.org/pygtk/stable/pango-markup-language.html)
`-dump` `-dump`
@ -696,7 +695,7 @@ Position **rofi** over the window with the given X11 window ID.
`-keep-right` `-keep-right`
Set ellipsize mode to start. So end of string is visible. Set ellipsize mode to start. So, the end of the string is visible.
### Message dialog ### Message dialog
@ -765,7 +764,7 @@ configuration {
`-click-to-exit` `-click-to-exit`
`-no-click-to-exit` `-no-click-to-exit`
Click the mouse outside of the **rofi** window to exit. Click the mouse outside the **rofi** window to exit.
Default: *enabled* Default: *enabled*
@ -782,7 +781,7 @@ To launch commands (for example, when using the ssh launcher), the user can ente
## DMENU REPLACEMENT ## DMENU REPLACEMENT
If `argv[0]` (calling command) is dmenu, **rofi** will start in dmenu mode. If `argv[0]` (calling command) is dmenu, **rofi** will start in dmenu mode.
This way it can be used as a drop-in replacement for dmenu. Just copy or symlink **rofi** to dmenu in `$PATH`. This way, it can be used as a drop-in replacement for dmenu. Just copy or symlink **rofi** to dmenu in `$PATH`.
ln -s /usr/bin/rofi /usr/bin/dmenu ln -s /usr/bin/rofi /usr/bin/dmenu
@ -794,44 +793,47 @@ Please see **rofi-theme(5)** manpage for more information on theming.
**rofi** has the following key bindings: **rofi** has the following key bindings:
* `Ctrl-v, Insert`: Paste from clipboard * `Control-v, Insert`: Paste from clipboard
* `Ctrl-Shift-v, Shift-Insert`: Paste primary selection * `Control-Shift-v, Shift-Insert`: Paste primary selection
* `Ctrl-u`: Clear the line * `Control-u`: Clear the line
* `Ctrl-a`: Beginning of line * `Control-a`: Beginning of line
* `Ctrl-e`: End of line * `Control-e`: End of line
* `Ctrl-f, Right`: Forward one character * `Control-f, Right`: Forward one character
* `Alt-f, Ctrl-Right`: Forward one word * `Alt-f, Control-Right`: Forward one word
* `Ctrl-b, Left`: Back one character * `Control-b, Left`: Back one character
* `Alt-b, Ctrl-Left`: Back one word * `Alt-b, Control-Left`: Back one word
* `Ctrl-d, Delete`: Delete character * `Control-d, Delete`: Delete character
* `Ctrl-Alt-d`: Delete word * `Control-Alt-d`: Delete word
* `Ctrl-h, Backspace, Shift-Backspace`: Backspace (delete previous character) * `Control-h, Backspace, Shift-Backspace`: Backspace (delete previous character)
* `Ctrl-Alt-h`: Delete previous word * `Control-Alt-h`: Delete previous word
* `Ctrl-j,Ctrl-m,Enter`: Accept entry * `Control-j,Control-m,Enter`: Accept entry
* `Ctrl-n,Down`: Select next entry * `Control-n,Down`: Select next entry
* `Ctrl-p,Up`: Select previous entry * `Control-p,Up`: Select previous entry
* `Page Up`: Go to previous page * `Page Up`: Go to previous page
* `Page Down`: Go to next page * `Page Down`: Go to next page
* `Ctrl-Page Up`: Go to previous column * `Control-Page Up`: Go to previous column
* `Ctrl-Page Down`: Go to next column * `Control-Page Down`: Go to next column
* `Ctrl-Enter`: Use entered text as a command (in `ssh/run modi`) * `Control-Enter`: Use entered text as a command (in `ssh/run modi`)
* `Shift-Enter`: Launch the application in a terminal (in run mode) * `Shift-Enter`: Launch the application in a terminal (in run mode)
* `Ctrl-Shift-Enter`: As Ctrl-Enter and run the command in terminal (in run mode) * `Control-Shift-Enter`: As Control-Enter and run the command in terminal (in run mode)
* `Shift-Enter`: Return the selected entry and move to the next item while keeping **rofi** open. (in dmenu) * `Shift-Enter`: Return the selected entry and move to the next item while keeping **rofi** open. (in dmenu)
* `Shift-Right`: Switch to the next mode. The list can be customized with the `-switchers` argument. * `Shift-Right`: Switch to the next mode. The list can be customized with the `-modi` argument.
* `Shift-Left`: Switch to the previous mode. The list can be customized with the `-switchers` argument. * `Shift-Left`: Switch to the previous mode. The list can be customized with the `-modi` argument.
* `Ctrl-Tab`: Switch to the next mode. The list can be customized with the `-switchers` argument. * `Control-Tab`: Switch to the next mode. The list can be customized with the `-modi` argument.
* `Ctrl-Shift-Tab`: Switch to the previous mode. The list can be customized with the `-switchers` argument. * `Control-Shift-Tab`: Switch to the previous mode. The list can be customized with the `-modi` argument.
* `Ctrl-space`: Set selected item as input text. * `Control-space`: Set selected item as input text.
* `Shift-Del`: Delete entry from history. * `Shift-Del`: Delete entry from history.
* `grave`: Toggle case sensitivity. * `grave`: Toggle case sensitivity.
* `Alt-grave`: Toggle sorting. * `Alt-grave`: Toggle sorting.
* `Alt-Shift-S`: Take a screenshot and store it in the Pictures directory. * `Alt-Shift-S`: Take a screenshot and store it in the Pictures directory.
* `Ctrl-l`: File complete for run dialog. * `Control-l`: File complete for run dialog.
This list might not be complete, to get a full list of all key bindings
supported in your rofi, see `rofi -h`. The options starting with `-kb` are keybindings.
Key bindings can be modified using the configuration systems. Multiple keys can be bound
to one action by comma separating them. For example `-kb-primary-paste "Conctrol+v,Insert"`
To get a full list of key bindings on the commandline, see `rofi -h`.
The options starting with `-kb` are keybindings.
Key bindings can be modified using the configuration systems.
To get a searchable list of key bindings, run `rofi -show keys`. 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. A key binding starting with `!` will act when all keys have been released.
@ -878,10 +880,10 @@ When pressing the `mode-complete` binding (`Control-l`), you can use the File Br
passing a file as argument if specified in the desktop file. passing a file as argument if specified in the desktop file.
The DRUN mode tries to follows the [XDG Desktop Entry The DRUN mode tries to follow the [XDG Desktop Entry
Specification](https://freedesktop.org/wiki/Specifications/desktop-entry-spec/) and should be compatible with Specification](https://freedesktop.org/wiki/Specifications/desktop-entry-spec/) and should be compatible with
applications using this standard. Some application create invalid desktop files, **rofi** will discard these entries. applications using this standard. Some applications create invalid desktop files, **rofi** will discard these entries.
See de debugging section how to get more information from the DRUN mode, this will print why desktop files are See the debugging section for more info on DRUN mode, this will print why desktop files are
discarded. discarded.
There are two advanced options to tweak the behaviour: There are two advanced options to tweak the behaviour:
@ -1018,12 +1020,12 @@ been released.
**rofi** support can be obtained: **rofi** support can be obtained:
* [GitHub Discussions](https://github.com/davatorium/rofi/discussions) * [GitHub Discussions](https://github.com/davatorium/rofi/discussions)
* [Forum (reddit)](https://reddit.com/r/qtools//) * [Forum (Reddit)](https://reddit.com/r/qtools//)
* [IRC](irc://irc.libera.chat:6697/#rofi) (#rofi on irc.libera.chat), * [IRC](irc://irc.libera.chat:6697/#rofi) (#rofi on irc.libera.chat),
## DEBUGGING ## DEBUGGING
To debug it is smart to first try disabling your custom configuration: To debug, it is smart to first try disabling your custom configuration:
`-no-config` `-no-config`
Disable parsing of configuration. This runs rofi in *stock* mode. Disable parsing of configuration. This runs rofi in *stock* mode.
@ -1036,7 +1038,7 @@ Disables the loading of plugins.
To further debug the plugin, you can get a trace with (lots of) debug information. This debug output can be enabled for To further debug the plugin, you can get a trace with (lots of) debug information. This debug output can be enabled for
multiple parts in rofi using the glib debug framework. Debug domains can be enabled by setting the G_MESSAGES_DEBUG multiple parts in rofi using the glib debug framework. Debug domains can be enabled by setting the G_MESSAGES_DEBUG
environment variable. At creation of this page the following debug domains exists: environment variable. At the time of creation of this page, the following debug domains exist:
* all: Show debug information from all domains. * all: Show debug information from all domains.
* X11Helper: The X11 Helper functions. * X11Helper: The X11 Helper functions.
@ -1060,7 +1062,7 @@ environment variable. At creation of this page the following debug domains exist
The output of this can provide useful information when writing an issue. The output of this can provide useful information when writing an issue.
More information (possibly outdated) see [this](https://github.com/DaveDavenport/rofi/wiki/Debugging Rofi) wiki entry. More information (possibly outdated) see [this](https://github.com/DaveDavenport/rofi/wiki/Debugging%20Rofi) wiki entry.
## ISSUE TRACKER ## ISSUE TRACKER

View file

@ -1,6 +1,10 @@
#ifndef ROFI_DIALOGS_DMENU_SCRIPT_SHARED_H #ifndef ROFI_DIALOGS_DMENU_SCRIPT_SHARED_H
#define ROFI_DIALOGS_DMENU_SCRIPT_SHARED_H #define ROFI_DIALOGS_DMENU_SCRIPT_SHARED_H
#include <glib.h>
#include <mode.h>
#include <stdint.h>
typedef struct { typedef struct {
/** Entry content. (visible part) */ /** Entry content. (visible part) */
char *entry; char *entry;

View file

@ -29,7 +29,7 @@
#define ROFI_KEYB_H #define ROFI_KEYB_H
#include <glib.h> #include <glib.h>
#include "nkutils-bindings.h" #include <nkutils-bindings.h>
/** /**
* @defgroup KEYB KeyboardBindings * @defgroup KEYB KeyboardBindings

View file

@ -71,6 +71,9 @@ const Mode *rofi_get_mode(unsigned int index);
*/ */
void rofi_add_error_message(GString *str); void rofi_add_error_message(GString *str);
/**
* Clear the list of stored error messages.
*/
void rofi_clear_error_messages(void); void rofi_clear_error_messages(void);
/** /**
* @param code the code to return * @param code the code to return

View file

@ -185,8 +185,11 @@ typedef struct {
char *application_fallback_icon; char *application_fallback_icon;
} Settings; } Settings;
/** Default number of lines in the list view */
#define DEFAULT_MENU_LINES 15 #define DEFAULT_MENU_LINES 15
/** Default number of columns in the list view */
#define DEFAULT_MENU_COLUMNS 1 #define DEFAULT_MENU_COLUMNS 1
/** Default window width */
#define DEFAULT_MENU_WIDTH 50.0f #define DEFAULT_MENU_WIDTH 50.0f
/** Global Settings structure. */ /** Global Settings structure. */

View file

@ -85,10 +85,13 @@ typedef struct ThemeWidget {
extern ThemeWidget *rofi_theme; extern ThemeWidget *rofi_theme;
/** /**
* Used to store config options. * Used to store theme.
*/ */
extern ThemeWidget *rofi_theme; extern ThemeWidget *rofi_theme;
/**
* Used to store config options.
*/
extern ThemeWidget *rofi_configuration; extern ThemeWidget *rofi_configuration;
/** /**
@ -108,6 +111,13 @@ ThemeWidget *rofi_theme_find_or_create_name(ThemeWidget *base,
* Print out the widget to the commandline. * Print out the widget to the commandline.
*/ */
void rofi_theme_print(ThemeWidget *widget); void rofi_theme_print(ThemeWidget *widget);
/**
* @param widget The widget handle.
* @param index The indenting index.
*
* Print out the widget to the commandline indented by index.
*/
void rofi_theme_print_index(ThemeWidget *widget, int index); void rofi_theme_print_index(ThemeWidget *widget, int index);
/** /**
@ -353,6 +363,17 @@ void distance_get_linestyle(RofiDistance d, cairo_t *draw);
*/ */
ThemeWidget *rofi_theme_find_widget(const char *name, const char *state, ThemeWidget *rofi_theme_find_widget(const char *name, const char *state,
gboolean exact); gboolean exact);
/**
* @param name The name of the element to find.
* @param state The state of the element.
* @param exact If the match should be exact, or parent can be included.
*
* Find the configuration element. If not exact, the closest specified element
* is returned.
*
* @returns the ThemeWidget if found, otherwise NULL.
*/
ThemeWidget *rofi_config_find_widget(const char *name, const char *state, ThemeWidget *rofi_config_find_widget(const char *name, const char *state,
gboolean exact); gboolean exact);

View file

@ -30,7 +30,6 @@
#include "mode.h" #include "mode.h"
#include <xcb/xcb.h> #include <xcb/xcb.h>
/** /**
* @defgroup View View * @defgroup View View
* *
@ -298,7 +297,7 @@ void __create_window(MenuFlags menu_flags);
xcb_window_t rofi_view_get_window(void); xcb_window_t rofi_view_get_window(void);
/** @} */ /** @} */
/*** /**
* @defgroup ViewThreadPool ViewThreadPool * @defgroup ViewThreadPool ViewThreadPool
* @ingroup View * @ingroup View
* *

View file

@ -30,7 +30,6 @@
#include "rofi-types.h" #include "rofi-types.h"
#include "widget.h" #include "widget.h"
#include "rofi-types.h"
/** /**
* @defgroup box box * @defgroup box box

View file

@ -29,13 +29,14 @@
#define ROFI_XCB_INTERNAL_H #define ROFI_XCB_INTERNAL_H
/** Indication we accept that startup notification api is not yet frozen */ /** Indication we accept that startup notification api is not yet frozen */
#define SN_API_NOT_YET_FROZEN #define SN_API_NOT_YET_FROZEN
#include <glib.h>
#include <libsn/sn.h> #include <libsn/sn.h>
#include "libgwater-xcb.h" #include <libgwater-xcb.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h> #include <xcb/xcb_ewmh.h>
#include "nkutils-bindings.h" #include <nkutils-bindings.h>
/** /**
* Structure to keep xcb stuff around. * Structure to keep xcb stuff around.

View file

@ -34,8 +34,10 @@
%{ %{
#include "config.h" #include "config.h"
#include "resources.h"
#include <stdio.h> #include <stdio.h>
#include <glib.h> #include <glib.h>
#include <gio/gio.h>
#include <helper.h> #include <helper.h>
#include <math.h> #include <math.h>
#include <strings.h> #include <strings.h>
@ -56,6 +58,8 @@ typedef enum {
PT_FILE, PT_FILE,
/** Parse a string */ /** Parse a string */
PT_STRING, PT_STRING,
/** Parse a string */
PT_STRING_ALLOC,
/** Parse environment */ /** Parse environment */
PT_ENV PT_ENV
} ParseType; } ParseType;
@ -75,12 +79,13 @@ typedef struct _ParseObject {
int str_len; int str_len;
/** String */ /** String */
const char *input_str; const char *input_str;
/** For where we need to free at end. (PT_STRING_ALLOC); */
char *malloc_str;
/** Position in file */ /** Position in file */
YYLTYPE location; YYLTYPE location;
} ParseObject; } ParseObject;
GList *imported_files = NULL;
GList *prev_imported_files = NULL; GList *prev_imported_files = NULL;
GQueue *file_queue = NULL; GQueue *file_queue = NULL;
GQueue *queue = NULL; GQueue *queue = NULL;
@ -127,6 +132,7 @@ static double rofi_theme_parse_convert_hex ( char high, char low)
break;\ break;\
}\ }\
case PT_ENV:\ case PT_ENV:\
case PT_STRING_ALLOC:\
case PT_STRING:\ case PT_STRING:\
{\ {\
yy_size_t len = MIN (max_size, current->str_len);\ yy_size_t len = MIN (max_size, current->str_len);\
@ -138,6 +144,7 @@ static double rofi_theme_parse_convert_hex ( char high, char low)
} else {\ } else {\
result = 0;\ result = 0;\
}\ }\
break;\
}\ }\
}\ }\
}\ }\
@ -273,6 +280,7 @@ C_COMMENT_OPEN "/*"
INCLUDE "@import" INCLUDE "@import"
THEME "@theme" THEME "@theme"
DEFAULT (?i:\"default\"?)
MEDIA "@media" MEDIA "@media"
@ -354,7 +362,6 @@ if ( queue == NULL ) {
BEGIN(INCLUDE); BEGIN(INCLUDE);
} }
<INITIAL>{THEME} { <INITIAL>{THEME} {
//rofi_theme_reset();
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(INCLUDE); BEGIN(INCLUDE);
return T_RESET_THEME; return T_RESET_THEME;
@ -363,6 +370,32 @@ if ( queue == NULL ) {
<INCLUDE>{WHITESPACE} {} <INCLUDE>{WHITESPACE} {}
/** Parse path. Last element in this INCLUDE */ /** Parse path. Last element in this INCLUDE */
<INCLUDE>{DEFAULT} {
ParseObject *top = g_queue_peek_head ( file_queue );
g_assert ( top != NULL );
GBytes *theme_data = g_resource_lookup_data( resources_get_resource(),
"/org/qtools/rofi/default.rasi", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
if (theme_data) {
const char *theme = g_bytes_get_data(theme_data, NULL);
top->location = *yylloc;
ParseObject *po = g_malloc0(sizeof(ParseObject));
po->type = PT_STRING_ALLOC;
po->malloc_str = g_strdup(theme);
po->input_str = po->malloc_str;
po->str_len = strlen(po->malloc_str)-1;
current = po;
g_queue_push_head ( file_queue, po );
g_bytes_unref(theme_data);
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 = NULL;//"default theme";
}
// Pop out of include.
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
}
<INCLUDE>{STRING} { <INCLUDE>{STRING} {
yytext[yyleng-1] = '\0'; yytext[yyleng-1] = '\0';
ParseObject *top = g_queue_peek_head ( file_queue ); ParseObject *top = g_queue_peek_head ( file_queue );
@ -370,32 +403,26 @@ if ( queue == NULL ) {
char *file2 = helper_get_theme_path ( &yytext[1], ".rasi" ); char *file2 = helper_get_theme_path ( &yytext[1], ".rasi" );
char *filename = rofi_theme_parse_prepare_file ( file2, top->filename ); char *filename = rofi_theme_parse_prepare_file ( file2, top->filename );
g_free ( file2 ); g_free ( file2 );
if ( g_list_find_custom ( imported_files, filename, (GCompareFunc)g_strcmp0 ) != NULL ) { FILE *f = fopen ( filename, "rb" );
g_debug ( "Skipping file: '%s' already parsed.", filename ); if ( f ) {
} else { top->location = *yylloc;
g_debug ( "Parsing file: '%s'", filename ); ParseObject *po = g_malloc0(sizeof(ParseObject));
FILE *f = fopen ( filename, "rb" ); po->type = PT_FILE;
if ( f ) { po->filename = filename;
top->location = *yylloc; po->filein = f;
ParseObject *po = g_malloc0(sizeof(ParseObject)); current = po;
po->type = PT_FILE; g_queue_push_head ( file_queue, po );
po->filename = filename;
po->filein = f;
current = po;
g_queue_push_head ( file_queue, po );
imported_files = g_list_append ( imported_files, po->filename );
yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE )); yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
yylloc->first_line = yylloc->last_line = 1; yylloc->first_line = yylloc->last_line = 1;
yylloc->first_column = yylloc->last_column = 1; yylloc->first_column = yylloc->last_column = 1;
yylloc->filename = current->filename; yylloc->filename = current->filename;
} else { } else {
char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>", char *str = g_markup_printf_escaped ( "Failed to open theme: <i>%s</i>\nError: <b>%s</b>",
filename, strerror ( errno ) ); filename, strerror ( errno ) );
rofi_add_error_message ( g_string_new ( str ) ); rofi_add_error_message ( g_string_new ( str ) );
g_free ( str ); g_free ( str );
g_free(filename); g_free(filename);
}
} }
// Pop out of include. */ // Pop out of include. */
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
@ -515,7 +542,6 @@ if ( queue == NULL ) {
po->str_len = strlen(val); po->str_len = strlen(val);
current = po; current = po;
g_queue_push_head ( file_queue, po ); g_queue_push_head ( file_queue, po );
imported_files = g_list_append ( imported_files, po->filename );
yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE )); yypush_buffer_state (yy_create_buffer ( 0, YY_BUF_SIZE ));
yylloc->first_line = yylloc->last_line = 1; yylloc->first_line = yylloc->last_line = 1;
@ -666,6 +692,9 @@ if ( queue == NULL ) {
if ( po->type == PT_FILE ) { if ( po->type == PT_FILE ) {
fclose ( po->filein ); fclose ( po->filein );
} }
if ( po->type == PT_STRING_ALLOC ) {
g_free( po->malloc_str);
}
g_free ( po ); g_free ( po );
} }
po = g_queue_peek_head ( file_queue ); po = g_queue_peek_head ( file_queue );
@ -799,7 +828,6 @@ gboolean rofi_theme_parse_file ( const char *file )
po->filename = filename; po->filename = filename;
po->filein = yyin; po->filein = yyin;
current = po; current = po;
imported_files = g_list_append ( imported_files, po->filename );
g_queue_push_head ( file_queue, po ); g_queue_push_head ( file_queue, po );
g_debug ( "Parsing top file: '%s'", filename ); g_debug ( "Parsing top file: '%s'", filename );
@ -812,13 +840,14 @@ gboolean rofi_theme_parse_file ( const char *file )
if ( po->type == PT_FILE ) { if ( po->type == PT_FILE ) {
fclose ( po->filein ); fclose ( po->filein );
} }
if ( po->type == PT_STRING_ALLOC ) {
g_free( po->malloc_str);
}
g_free ( po ); g_free ( po );
} }
} }
// Free up. // Free up.
g_list_free_full ( imported_files, g_free );
g_queue_free ( file_queue ); g_queue_free ( file_queue );
imported_files = NULL;
file_queue = NULL; file_queue = NULL;
if ( parser_retv != 0 ) { if ( parser_retv != 0 ) {
return TRUE; return TRUE;
@ -847,12 +876,13 @@ gboolean rofi_theme_parse_string ( const char *string )
if ( po->type == PT_FILE ) { if ( po->type == PT_FILE ) {
fclose ( po->filein ); fclose ( po->filein );
} }
if ( po->type == PT_STRING_ALLOC ) {
g_free( po->malloc_str);
}
g_free ( po ); g_free ( po );
} }
} }
// Free up. // Free up.
g_list_free_full ( imported_files, g_free );
imported_files = NULL;
g_queue_free ( file_queue ); g_queue_free ( file_queue );
file_queue = NULL; file_queue = NULL;
if ( parser_retv != 0 ) { if ( parser_retv != 0 ) {

View file

@ -30,7 +30,6 @@
%locations %locations
%glr-parser %glr-parser
%skeleton "glr.c" %skeleton "glr.c"
%debug
%parse-param {const char *what} %parse-param {const char *what}
%code requires { %code requires {
#include "theme.h" #include "theme.h"
@ -267,6 +266,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b )
%token T_MEDIA_SEP "-" %token T_MEDIA_SEP "-"
%type <theme> t_entry_list %type <theme> t_entry_list
%type <theme> t_entry_list_included
%type <list> t_entry_name_path %type <list> t_entry_name_path
%type <list> t_entry_name_path_selectors %type <list> t_entry_name_path_selectors
%type <list> t_color_list %type <list> t_color_list
@ -307,13 +307,12 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b )
* First have the configuration blocks, then the theme. * First have the configuration blocks, then the theme.
*/ */
t_main t_main
: t_configuration_list t_entry_list { : t_configuration_list t_entry_list_included {
// Dummy at this point. // Dummy at this point.
if ( rofi_theme == NULL ) { if ( rofi_theme == NULL ) {
rofi_theme_reset(); rofi_theme_reset();
} }
rofi_theme_widget_add_properties ( rofi_theme, $2->properties ); rofi_theme_widget_add_properties ( rofi_theme, $2->properties );
for ( unsigned int i = 0; i < $2->num_widgets; i++ ) { for ( unsigned int i = 0; i < $2->num_widgets; i++ ) {
ThemeWidget *d = $2->widgets[i]; ThemeWidget *d = $2->widgets[i];
@ -340,16 +339,22 @@ t_name_prefix_optional
| %empty {} | %empty {}
; ;
t_entry_list_included:
t_entry_list {
$$ =$1;
}
| t_entry_list_included T_RESET_THEME t_entry_list {
rofi_theme_reset();
rofi_theme_free($1);
$$ = $3;
}
t_entry_list: t_entry_list:
%empty { %empty {
$$ = g_slice_new0 ( ThemeWidget ); $$ = g_slice_new0 ( ThemeWidget );
} }
| t_entry_list T_RESET_THEME {
rofi_theme_reset();
rofi_theme_free($1);
$$ = g_slice_new0 ( ThemeWidget );
}
| t_entry_list t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE | t_entry_list t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE
{ {
for ( GList *liter = g_list_first ( $3); liter; liter = g_list_next ( liter ) ) { for ( GList *liter = g_list_first ( $3); liter; liter = g_list_next ( liter ) ) {

View file

@ -1,5 +1,5 @@
project('rofi', 'c', project('rofi', 'c',
version: '1.6.1-wayland-dev', version: '1.7.0-wayland',
meson_version: '>=0.47.0', meson_version: '>=0.47.0',
license: [ 'MIT' ], license: [ 'MIT' ],
default_options: [ default_options: [
@ -359,6 +359,7 @@ test('widget test', executable('widget.test', [
'test/widget-test.c', 'test/widget-test.c',
theme_parser, theme_parser,
theme_lexer, theme_lexer,
default_theme,
], ],
objects: rofi.extract_objects([ objects: rofi.extract_objects([
'source/widgets/widget.c', 'source/widgets/widget.c',
@ -376,6 +377,7 @@ test('box test', executable('box.test', [
'test/box-test.c', 'test/box-test.c',
theme_parser, theme_parser,
theme_lexer, theme_lexer,
default_theme,
], ],
objects: rofi.extract_objects([ objects: rofi.extract_objects([
'source/widgets/widget.c', 'source/widgets/widget.c',
@ -392,6 +394,7 @@ test('scrollbar test', executable('scrollbar.test', [
'test/scrollbar-test.c', 'test/scrollbar-test.c',
theme_parser, theme_parser,
theme_lexer, theme_lexer,
default_theme,
], ],
objects: rofi.extract_objects([ objects: rofi.extract_objects([
'source/widgets/widget.c', 'source/widgets/widget.c',
@ -408,6 +411,7 @@ test('textbox test', executable('textbox.test', [
'test/textbox-test.c', 'test/textbox-test.c',
theme_parser, theme_parser,
theme_lexer, theme_lexer,
default_theme,
], ],
objects: rofi.extract_objects([ objects: rofi.extract_objects([
'source/widgets/widget.c', 'source/widgets/widget.c',
@ -467,6 +471,7 @@ if check.found()
'test/theme-parser-test.c', 'test/theme-parser-test.c',
theme_lexer, theme_lexer,
theme_parser, theme_parser,
default_theme,
], ],
objects: rofi.extract_objects([ objects: rofi.extract_objects([
'config/config.c', 'config/config.c',
@ -510,20 +515,6 @@ if check.found()
endif endif
run_target('test-x', command: [ 'test/run_all_tests.sh' ], depends: [ rofi ])
uncrustify = find_program('uncrustify', required: false)
if uncrustify.found()
run_target('indent',
command: [
uncrustify,
'-c', join_paths(meson.source_root(), 'data', 'uncrustify.cfg'),
'--replace',
rofi_sources
],
)
endif
rofi_sources += theme_lexer_sources rofi_sources += theme_lexer_sources
rofi_sources += theme_parser_sources rofi_sources += theme_parser_sources

View file

@ -9,14 +9,39 @@ yet converted to the new format, I hope for some understanding. Even though this
deprecation in previous releases and consequential removal of these options is needed for two reasons. deprecation in previous releases and consequential removal of these options is needed for two reasons.
The most important one is to keep rofi maintainable and secondary to open possibility to overhaul the config system in The most important one is to keep rofi maintainable and secondary to open possibility to overhaul the config system in
the future and with that fixing some long standing bugs and add new options that the future and with that fixing some long standing bugs and add new options that
where hindered by the almost 10 year old system. where hindered by the almost 10 year old system, the new system has been around for more than 4 years.
Beside mostly bug-fixes and removal of deprecated options, we also improved the theming and added features to help in Beside mostly bug-fixes and removal of deprecated options, we also improved the theming and added features to help in
some of the more 'off-script' use of rofi. some of the more 'off-script' use of rofi.
This release was made possible by many contributors, see below for a full list. Big thanks again to SardemF77 and This release was made possible by many contributors, see below for a full list. Big thanks again to SardemFF7 and
TonCherAmi. TonCherAmi.
## Default theme loading
In older version of **rofi** the default theme was (almost) always loaded based on some unclear rules, sometimes
some random patch code was loaded and sometimes no theme was loaded before loading another theme.
The current version of rofi this is hopefully more logic. It loads the default
theme by default using the default configuration. (Can be disabled by `-no-default-config`).
Using `-theme`, or `@theme` primitive will discard the theme completely.
So the below css completely removes the default theme, and loads `iggy`.
```css
configuration {
}
@theme "iggy"
element {
children: [element-icon, element-text];
}
```
## File Browser ## File Browser
TonCherAmi made several very nice usability improvements to the file-browser. His changes allow you to define sorting TonCherAmi made several very nice usability improvements to the file-browser. His changes allow you to define sorting
@ -47,7 +72,7 @@ configuration {
## File Completion ## File Completion
In rofi 1.7.0 a long awaited patch I wrote many years ago landed into the rofi. In rofi 1.7.0 a long awaited patch I wrote many years ago landed into the rofi.
This patch adds some basic completion support by changing modi. Currently it This patch adds some basic completion support by chaining modi. Currently it
only supports chaining the FileBrowser mode. This allows you to launch an only supports chaining the FileBrowser mode. This allows you to launch an
application with a file as argument. This is currently supported in the Run application with a file as argument. This is currently supported in the Run
and the DRun modi by pressing the `Control-l` keybinding. For the Run mode it and the DRun modi by pressing the `Control-l` keybinding. For the Run mode it
@ -324,6 +349,20 @@ message {
``` ```
* FIX: [Build] Fix CI.
* FIX: [Theme] Discard old theme, when explicitly passing one on command line.
In previous version there was a bug when passing `-theme` on commandline did not discard old theme.
This caused problems loading themes (as it merged two themes instead of loading them).
To get old behaviour on commandline do:
```bash
rofi -theme-str '@import "mytheme"' -show drun
````
* REMOVE: -dump-xresources * REMOVE: -dump-xresources
* REMOVE: -fullscreen * REMOVE: -fullscreen
* REMOVE: -show-match * REMOVE: -show-match

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gresources> <gresources>
<gresource prefix="/org/qtools/rofi"> <gresource prefix="/org/qtools/rofi">
<file alias="default_theme.rasi">doc/default_theme.rasi</file> <file alias="default.rasi">doc/default_theme.rasi</file>
<file alias="default_configuration.rasi">doc/default_configuration.rasi</file> <file alias="default_configuration.rasi">doc/default_configuration.rasi</file>
</gresource> </gresource>
</gresources> </gresources>

View file

@ -138,7 +138,9 @@ select_theme()
local MESG="""You can preview themes by hitting <b>Enter</b>. local MESG="""You can preview themes by hitting <b>Enter</b>.
<b>Alt-a</b> to accept the new theme. <b>Alt-a</b> to accept the new theme.
<b>Escape</b> to cancel <b>Escape</b> to cancel
Current theme: <b>${CUR}</b>""" Current theme: <b>${CUR}</b>
<span weight=\"bold\" size=\"xx-small\">When setting a new theme this will override previous theme settings.
Please update your config file if you have local modifications.</span>"""
THEME_FLAG= THEME_FLAG=
if [ -n "${SELECTED}" ] if [ -n "${SELECTED}" ]
then then
@ -173,8 +175,8 @@ set_theme()
mkdir -p "${CDIR}" mkdir -p "${CDIR}"
fi fi
get_link=$(readlink -f "${CDIR}/config.rasi") get_link=$(readlink -f "${CDIR}/config.rasi")
${SED} -i "/@import.*/d" "${get_link}" ${SED} -i 's/^\s*\(@theme\s\+".*"\)/\/\/\1/' "${get_link}"
echo "@import \"${1}\"" >> "${get_link}" echo "@theme \"${1}\"" >> "${get_link}"
} }
############################################################################################################ ############################################################################################################

View file

@ -57,18 +57,33 @@
#include "rofi-icon-fetcher.h" #include "rofi-icon-fetcher.h"
/** The filename of the history cache file. */
#define DRUN_CACHE_FILE "rofi3.druncache" #define DRUN_CACHE_FILE "rofi3.druncache"
/** The filename of the drun quick-load cache file. */
#define DRUN_DESKTOP_CACHE_FILE "rofi-drun-desktop.cache" #define DRUN_DESKTOP_CACHE_FILE "rofi-drun-desktop.cache"
/** The group name used in desktop files */
char *DRUN_GROUP_NAME = "Desktop Entry"; char *DRUN_GROUP_NAME = "Desktop Entry";
/**
*The Internal data structure for the drun mode.
*/
typedef struct _DRunModePrivateData DRunModePrivateData; typedef struct _DRunModePrivateData DRunModePrivateData;
/**
* Used to determine the type of desktop file.
*/
typedef enum { typedef enum {
/** Unknown. */
DRUN_DESKTOP_ENTRY_TYPE_UNDETERMINED = 0, DRUN_DESKTOP_ENTRY_TYPE_UNDETERMINED = 0,
/** Application */
DRUN_DESKTOP_ENTRY_TYPE_APPLICATION, DRUN_DESKTOP_ENTRY_TYPE_APPLICATION,
/** Link */
DRUN_DESKTOP_ENTRY_TYPE_LINK, DRUN_DESKTOP_ENTRY_TYPE_LINK,
/** KDE Service File */
DRUN_DESKTOP_ENTRY_TYPE_SERVICE, DRUN_DESKTOP_ENTRY_TYPE_SERVICE,
/** Directory */
DRUN_DESKTOP_ENTRY_TYPE_DIRECTORY, DRUN_DESKTOP_ENTRY_TYPE_DIRECTORY,
} DRunDesktopEntryType; } DRunDesktopEntryType;
@ -90,9 +105,9 @@ typedef struct {
char *desktop_id; char *desktop_id;
/* Icon stuff */ /* Icon stuff */
char *icon_name; char *icon_name;
/* Icon size is used to indicate what size is requested by the gui. /* Icon size is used to indicate what size is requested by the
* secondary it indicates if the request for a lookup has been issued (0 not * gui. secondary it indicates if the request for a lookup has
* issued ) * been issued (0 not issued )
*/ */
int icon_size; int icon_size;
/* Surface holding the icon. */ /* Surface holding the icon. */
@ -109,13 +124,13 @@ typedef struct {
char **keywords; char **keywords;
/* Comments */ /* Comments */
char *comment; char *comment;
/* Underlying key-file. */
GKeyFile *key_file; GKeyFile *key_file;
/* Used for sorting. */
gint sort_index; gint sort_index;
/* UID for the icon to display */
uint32_t icon_fetch_uid; uint32_t icon_fetch_uid;
/* Type of desktop file */
DRunDesktopEntryType type; DRunDesktopEntryType type;
} DRunModeEntry; } DRunModeEntry;
@ -125,16 +140,26 @@ typedef struct {
gboolean enabled_display; gboolean enabled_display;
} DRunEntryField; } DRunEntryField;
/** The fields that can be displayed and used for matching */
typedef enum { typedef enum {
/** Name */
DRUN_MATCH_FIELD_NAME, DRUN_MATCH_FIELD_NAME,
/** Generic Name */
DRUN_MATCH_FIELD_GENERIC, DRUN_MATCH_FIELD_GENERIC,
/** Exec */
DRUN_MATCH_FIELD_EXEC, DRUN_MATCH_FIELD_EXEC,
/** List of categories */
DRUN_MATCH_FIELD_CATEGORIES, DRUN_MATCH_FIELD_CATEGORIES,
/** List of keywords */
DRUN_MATCH_FIELD_KEYWORDS, DRUN_MATCH_FIELD_KEYWORDS,
/** Comment */
DRUN_MATCH_FIELD_COMMENT, DRUN_MATCH_FIELD_COMMENT,
/** Number of DRunMatchingFields entries. */
DRUN_MATCH_NUM_FIELDS, DRUN_MATCH_NUM_FIELDS,
} DRunMatchingFields; } DRunMatchingFields;
/** Stores what fields should be matched on user input. based on user setting.
*/
static DRunEntryField matching_entry_fields[DRUN_MATCH_NUM_FIELDS] = { static DRunEntryField matching_entry_fields[DRUN_MATCH_NUM_FIELDS] = {
{ {
.entry_field_name = "name", .entry_field_name = "name",
@ -328,14 +353,14 @@ static void exec_cmd_entry(DRunModeEntry *e, const char *path) {
if (e->key_file == NULL) { if (e->key_file == NULL) {
GKeyFile *kf = g_key_file_new(); GKeyFile *kf = g_key_file_new();
GError *error = NULL; GError *key_error = NULL;
gboolean res = g_key_file_load_from_file(kf, e->path, 0, &error); gboolean res = g_key_file_load_from_file(kf, e->path, 0, &key_error);
if (res) { if (res) {
e->key_file = kf; e->key_file = kf;
} else { } else {
g_warning("[%s] [%s] Failed to parse desktop file because: %s.", g_warning("[%s] [%s] Failed to parse desktop file because: %s.",
e->app_id, e->path, error->message); e->app_id, e->path, key_error->message);
g_error_free(error); g_error_free(key_error);
g_key_file_free(kf); g_key_file_free(kf);
return; return;
@ -370,10 +395,10 @@ static void exec_cmd_entry(DRunModeEntry *e, const char *path) {
gboolean terminal = gboolean terminal =
g_key_file_get_boolean(e->key_file, e->action, "Terminal", NULL); g_key_file_get_boolean(e->key_file, e->action, "Terminal", NULL);
if (helper_execute_command(exec_path, fp, terminal, sn ? &context : NULL)) { if (helper_execute_command(exec_path, fp, terminal, sn ? &context : NULL)) {
char *path = g_build_filename(cache_dir, DRUN_CACHE_FILE, NULL); char *drun_cach_path = g_build_filename(cache_dir, DRUN_CACHE_FILE, NULL);
// Store it based on the unique identifiers (desktop_id). // Store it based on the unique identifiers (desktop_id).
history_set(path, e->desktop_id); history_set(drun_cach_path, e->desktop_id);
g_free(path); g_free(drun_cach_path);
} }
g_free(wmclass); g_free(wmclass);
g_free(exec_path); g_free(exec_path);
@ -802,6 +827,7 @@ static gint drun_int_sort_list(gconstpointer a, gconstpointer b,
* Cache voodoo * * Cache voodoo *
*******************************************/ *******************************************/
/** Version of the DRUN cache file format. */
#define CACHE_VERSION 2 #define CACHE_VERSION 2
static void drun_write_str(FILE *fd, const char *str) { static void drun_write_str(FILE *fd, const char *str) {
size_t l = (str == NULL ? 0 : strlen(str)); size_t l = (str == NULL ? 0 : strlen(str));
@ -1441,6 +1467,7 @@ static char *drun_get_message(const Mode *sw) {
return NULL; return NULL;
} }
#include "mode-private.h" #include "mode-private.h"
/** The DRun Mode interface. */
Mode drun_mode = {.name = "drun", Mode drun_mode = {.name = "drun",
.cfg_name_key = "display-drun", .cfg_name_key = "display-drun",
._init = drun_mode_init, ._init = drun_mode_init,

View file

@ -93,9 +93,15 @@ typedef struct {
unsigned int array_length; unsigned int array_length;
} FileBrowserModePrivateData; } FileBrowserModePrivateData;
/**
* The sorting settings used in file-browser.
*/
struct { struct {
/** Field to sort on. */
enum FBSortingMethod sorting_method; enum FBSortingMethod sorting_method;
/** If sorting on time, what time entry. */
enum FBSortingTime sorting_time; enum FBSortingTime sorting_time;
/** If we want to display directories above files. */
gboolean directories_first; gboolean directories_first;
} file_browser_config = { } file_browser_config = {
.sorting_method = FB_SORT_NAME, .sorting_method = FB_SORT_NAME,

View file

@ -296,9 +296,9 @@ static RunEntry *get_apps(unsigned int *length) {
continue; continue;
} }
if (is_homedir) { if (is_homedir) {
gchar *fpath = g_build_filename(dirname, dent->d_name, NULL); gchar *full_path = g_build_filename(dirname, dent->d_name, NULL);
gboolean b = g_file_test(fpath, G_FILE_TEST_IS_EXECUTABLE); gboolean b = g_file_test(full_path, G_FILE_TEST_IS_EXECUTABLE);
g_free(fpath); g_free(full_path);
if (!b) { if (!b) {
continue; continue;
} }

View file

@ -201,20 +201,20 @@ static SshEntry *read_known_hosts_file(const char *path, SshEntry *retv,
int port = 0; int port = 0;
if (start[0] == '[') { if (start[0] == '[') {
start++; start++;
char *end = strchr(start, ']'); char *strend = strchr(start, ']');
if (end[1] == ':') { if (strend[1] == ':') {
*end = '\0'; *strend = '\0';
errno = 0; errno = 0;
gchar *endptr = NULL; gchar *endptr = NULL;
gint64 number = g_ascii_strtoll(&(end[2]), &endptr, 10); gint64 number = g_ascii_strtoll(&(strend[2]), &endptr, 10);
if (errno != 0) { if (errno != 0) {
g_warning("Failed to parse port number: %s.", &(end[2])); g_warning("Failed to parse port number: %s.", &(strend[2]));
} else if (endptr == &(end[2])) { } else if (endptr == &(strend[2])) {
g_warning("Failed to parse port number: %s, invalid number.", g_warning("Failed to parse port number: %s, invalid number.",
&(end[2])); &(strend[2]));
} else if (number < 0 || number > 65535) { } else if (number < 0 || number > 65535) {
g_warning("Failed to parse port number: %s, out of range.", g_warning("Failed to parse port number: %s, out of range.",
&(end[2])); &(strend[2]));
} else { } else {
port = number; port = number;
} }
@ -499,15 +499,16 @@ static SshEntry *get_ssh(SSHModePrivateData *pd, unsigned int *length) {
parse_ssh_config_file(pd, path, &retv, length, num_favorites); parse_ssh_config_file(pd, path, &retv, length, num_favorites);
if (config.parse_known_hosts == TRUE) { if (config.parse_known_hosts == TRUE) {
char *path = char *known_hosts_path =
g_build_filename(g_get_home_dir(), ".ssh", "known_hosts", NULL); g_build_filename(g_get_home_dir(), ".ssh", "known_hosts", NULL);
retv = read_known_hosts_file(path, retv, length); retv = read_known_hosts_file(known_hosts_path, retv, length);
g_free(path); g_free(known_hosts_path);
for (GList *iter = g_list_first(pd->user_known_hosts); iter; for (GList *iter = g_list_first(pd->user_known_hosts); iter;
iter = g_list_next(iter)) { iter = g_list_next(iter)) {
char *path = rofi_expand_path((const char *)iter->data); char *user_known_hosts_path = rofi_expand_path((const char *)iter->data);
retv = read_known_hosts_file((const char *)path, retv, length); retv = read_known_hosts_file((const char *)user_known_hosts_path, retv,
g_free(path); length);
g_free(user_known_hosts_path);
} }
} }
if (config.parse_hosts == TRUE) { if (config.parse_hosts == TRUE) {

View file

@ -538,90 +538,97 @@ static void _window_mode_load_data(Mode *sw, unsigned int cd) {
// we're working... // we're working...
pd->ids = winlist_new(); pd->ids = winlist_new();
xcb_get_property_cookie_t c = xcb_get_property_cookie_t prop_cookie =
xcb_ewmh_get_desktop_names(&xcb->ewmh, xcb->screen_nbr); xcb_ewmh_get_desktop_names(&xcb->ewmh, xcb->screen_nbr);
xcb_ewmh_get_utf8_strings_reply_t names; xcb_ewmh_get_utf8_strings_reply_t names;
int has_names = FALSE; int has_names = FALSE;
if (xcb_ewmh_get_desktop_names_reply(&xcb->ewmh, c, &names, NULL)) { if (xcb_ewmh_get_desktop_names_reply(&xcb->ewmh, prop_cookie, &names,
NULL)) {
has_names = TRUE; has_names = TRUE;
} }
// calc widths of fields // calc widths of fields
for (i = clients.windows_len - 1; i > -1; i--) { for (i = clients.windows_len - 1; i > -1; i--) {
client *c = window_client(pd, clients.windows[i]); client *winclient = window_client(pd, clients.windows[i]);
if ((c != NULL) && !c->xattr.override_redirect && if ((winclient != NULL) && !winclient->xattr.override_redirect &&
!client_has_window_type(c, xcb->ewmh._NET_WM_WINDOW_TYPE_DOCK) && !client_has_window_type(winclient,
!client_has_window_type(c, xcb->ewmh._NET_WM_WINDOW_TYPE_DESKTOP) && xcb->ewmh._NET_WM_WINDOW_TYPE_DOCK) &&
!client_has_state(c, xcb->ewmh._NET_WM_STATE_SKIP_PAGER) && !client_has_window_type(winclient,
!client_has_state(c, xcb->ewmh._NET_WM_STATE_SKIP_TASKBAR)) { xcb->ewmh._NET_WM_WINDOW_TYPE_DESKTOP) &&
!client_has_state(winclient, xcb->ewmh._NET_WM_STATE_SKIP_PAGER) &&
!client_has_state(winclient, xcb->ewmh._NET_WM_STATE_SKIP_TASKBAR)) {
pd->clf_len = pd->clf_len =
MAX(pd->clf_len, MAX(pd->clf_len, (winclient->class != NULL)
(c->class != NULL) ? (g_utf8_strlen(c->class, -1)) : 0); ? (g_utf8_strlen(winclient->class, -1))
: 0);
if (client_has_state(c, xcb->ewmh._NET_WM_STATE_DEMANDS_ATTENTION)) { if (client_has_state(winclient,
c->demands = TRUE; xcb->ewmh._NET_WM_STATE_DEMANDS_ATTENTION)) {
winclient->demands = TRUE;
} }
if ((c->hint_flags & XCB_ICCCM_WM_HINT_X_URGENCY) != 0) { if ((winclient->hint_flags & XCB_ICCCM_WM_HINT_X_URGENCY) != 0) {
c->demands = TRUE; winclient->demands = TRUE;
} }
if (c->window == curr_win_id) { if (winclient->window == curr_win_id) {
c->active = TRUE; winclient->active = TRUE;
} }
// find client's desktop. // find client's desktop.
xcb_get_property_cookie_t cookie; xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *r; xcb_get_property_reply_t *r;
c->wmdesktop = 0xFFFFFFFF; winclient->wmdesktop = 0xFFFFFFFF;
cookie = xcb_get_property(xcb->connection, 0, c->window, cookie = xcb_get_property(xcb->connection, 0, winclient->window,
xcb->ewmh._NET_WM_DESKTOP, XCB_ATOM_CARDINAL, xcb->ewmh._NET_WM_DESKTOP, XCB_ATOM_CARDINAL,
0, 1); 0, 1);
r = xcb_get_property_reply(xcb->connection, cookie, NULL); r = xcb_get_property_reply(xcb->connection, cookie, NULL);
if (r) { if (r) {
if (r->type == XCB_ATOM_CARDINAL) { if (r->type == XCB_ATOM_CARDINAL) {
c->wmdesktop = *((uint32_t *)xcb_get_property_value(r)); winclient->wmdesktop = *((uint32_t *)xcb_get_property_value(r));
} }
free(r); free(r);
} }
if (c->wmdesktop != 0xFFFFFFFF) { if (winclient->wmdesktop != 0xFFFFFFFF) {
if (has_names) { if (has_names) {
if ((current_window_manager & WM_PANGO_WORKSPACE_NAMES) == if ((current_window_manager & WM_PANGO_WORKSPACE_NAMES) ==
WM_PANGO_WORKSPACE_NAMES) { WM_PANGO_WORKSPACE_NAMES) {
char *output = NULL; char *output = NULL;
if (pango_parse_markup(_window_name_list_entry(names.strings, if (pango_parse_markup(
names.strings_len, _window_name_list_entry(names.strings, names.strings_len,
c->wmdesktop), winclient->wmdesktop),
-1, 0, NULL, &output, NULL, NULL)) { -1, 0, NULL, &output, NULL, NULL)) {
c->wmdesktopstr = g_strdup(_window_name_list_entry( winclient->wmdesktopstr = g_strdup(_window_name_list_entry(
names.strings, names.strings_len, c->wmdesktop)); names.strings, names.strings_len, winclient->wmdesktop));
c->wmdesktopstr_len = g_utf8_strlen(output, -1); winclient->wmdesktopstr_len = g_utf8_strlen(output, -1);
pd->wmdn_len = MAX(pd->wmdn_len, c->wmdesktopstr_len); pd->wmdn_len = MAX(pd->wmdn_len, winclient->wmdesktopstr_len);
g_free(output); g_free(output);
} else { } else {
c->wmdesktopstr = g_strdup("Invalid name"); winclient->wmdesktopstr = g_strdup("Invalid name");
pd->wmdn_len = pd->wmdn_len = MAX(pd->wmdn_len,
MAX(pd->wmdn_len, g_utf8_strlen(c->wmdesktopstr, -1)); g_utf8_strlen(winclient->wmdesktopstr, -1));
} }
} else { } else {
c->wmdesktopstr = g_markup_escape_text( winclient->wmdesktopstr = g_markup_escape_text(
_window_name_list_entry(names.strings, names.strings_len, _window_name_list_entry(names.strings, names.strings_len,
c->wmdesktop), winclient->wmdesktop),
-1); -1);
pd->wmdn_len = pd->wmdn_len =
MAX(pd->wmdn_len, g_utf8_strlen(c->wmdesktopstr, -1)); MAX(pd->wmdn_len, g_utf8_strlen(winclient->wmdesktopstr, -1));
} }
} else { } else {
c->wmdesktopstr = g_strdup_printf("%u", (uint32_t)c->wmdesktop); winclient->wmdesktopstr =
g_strdup_printf("%u", (uint32_t)winclient->wmdesktop);
pd->wmdn_len = pd->wmdn_len =
MAX(pd->wmdn_len, g_utf8_strlen(c->wmdesktopstr, -1)); MAX(pd->wmdn_len, g_utf8_strlen(winclient->wmdesktopstr, -1));
} }
} else { } else {
c->wmdesktopstr = g_strdup(""); winclient->wmdesktopstr = g_strdup("");
pd->wmdn_len = MAX(pd->wmdn_len, g_utf8_strlen(c->wmdesktopstr, -1)); pd->wmdn_len =
MAX(pd->wmdn_len, g_utf8_strlen(winclient->wmdesktopstr, -1));
} }
if (cd && c->wmdesktop != current_desktop) { if (cd && winclient->wmdesktop != current_desktop) {
continue; continue;
} }
winlist_append(pd->ids, c->window, NULL); winlist_append(pd->ids, winclient->window, NULL);
} }
} }

View file

@ -302,7 +302,6 @@ static void rofi_icon_fetcher_worker(thread_state *sdata,
const char *ext = g_strrstr(sentry->entry->name, "."); const char *ext = g_strrstr(sentry->entry->name, ".");
if (ext) { if (ext) {
printf("%s %s\r\n", sentry->entry->name, ext);
icon_path = helper_get_theme_path(sentry->entry->name, ext); icon_path = helper_get_theme_path(sentry->entry->name, ext);
} }
if (icon_path == NULL) { if (icon_path == NULL) {

View file

@ -843,7 +843,7 @@ int main(int argc, char *argv[]) {
"Pidfile location"); "Pidfile location");
/** default configuration */ /** default configuration */
{ if (find_arg("-no-default-config") < 0) {
GBytes *theme_data = g_resource_lookup_data( GBytes *theme_data = g_resource_lookup_data(
resources_get_resource(), "/org/qtools/rofi/default_configuration.rasi", resources_get_resource(), "/org/qtools/rofi/default_configuration.rasi",
G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
@ -963,6 +963,7 @@ int main(int argc, char *argv[]) {
TICK_N("Parse theme"); TICK_N("Parse theme");
rofi_theme_reset(); rofi_theme_reset();
if (rofi_theme_parse_file(config.theme)) { if (rofi_theme_parse_file(config.theme)) {
g_warning("Failed to parse theme: \"%s\"", config.theme);
// TODO: instantiate fallback theme.? // TODO: instantiate fallback theme.?
rofi_theme_free(rofi_theme); rofi_theme_free(rofi_theme);
rofi_theme = NULL; rofi_theme = NULL;
@ -1003,28 +1004,6 @@ int main(int argc, char *argv[]) {
windowid = config.monitor; windowid = config.monitor;
} }
} }
if (rofi_theme_is_empty()) {
GBytes *theme_data = g_resource_lookup_data(
resources_get_resource(), "/org/qtools/rofi/default_theme.rasi",
G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
if (theme_data) {
const char *theme = g_bytes_get_data(theme_data, NULL);
if (rofi_theme_parse_string((const char *)theme)) {
g_warning("Failed to parse default theme. Giving up..");
if (list_of_error_msgs) {
for (GList *iter = g_list_first(list_of_error_msgs); iter != NULL;
iter = g_list_next(iter)) {
g_warning("Error: %s%s%s", color_bold, ((GString *)iter->data)->str,
color_reset);
}
}
rofi_theme = NULL;
cleanup();
return EXIT_FAILURE;
}
g_bytes_unref(theme_data);
}
}
/** /**
* Make small commandline changes to the current theme. * Make small commandline changes to the current theme.
@ -1033,6 +1012,8 @@ int main(int argc, char *argv[]) {
if (theme_str) { if (theme_str) {
for (int index = 0; theme_str && theme_str[index]; index++) { for (int index = 0; theme_str && theme_str[index]; index++) {
if (rofi_theme_parse_string(theme_str[index])) { if (rofi_theme_parse_string(theme_str[index])) {
g_warning("Failed to parse -theme-str option: \"%s\"",
theme_str[index]);
rofi_theme_free(rofi_theme); rofi_theme_free(rofi_theme);
rofi_theme = NULL; rofi_theme = NULL;
} }

View file

@ -503,13 +503,13 @@ void rofi_theme_print_index(ThemeWidget *widget, int index) {
} }
if (g_list_length(list) > 0) { if (g_list_length(list) > 0) {
printf("%*s", index, ""); printf("%*s", index, "");
for (GList *iter = g_list_first(list); iter != NULL; for (GList *citer = g_list_first(list); citer != NULL;
iter = g_list_next(iter)) { citer = g_list_next(citer)) {
char *name = (char *)iter->data; char *name = (char *)citer->data;
fputs(name, stdout); fputs(name, stdout);
if (iter->prev == NULL && iter->next) { if (citer->prev == NULL && citer->next) {
putchar(' '); putchar(' ');
} else if (iter->next) { } else if (citer->next) {
putchar('.'); putchar('.');
} }
} }
@ -520,13 +520,13 @@ void rofi_theme_print_index(ThemeWidget *widget, int index) {
size_t property_name_length = 0; size_t property_name_length = 0;
g_hash_table_iter_init(&iter, widget->properties); g_hash_table_iter_init(&iter, widget->properties);
while (g_hash_table_iter_next(&iter, &key, &value)) { while (g_hash_table_iter_next(&iter, &key, &value)) {
Property *p = (Property *)value; Property *pv = (Property *)value;
property_name_length = MAX(strlen(p->name), property_name_length); property_name_length = MAX(strlen(pv->name), property_name_length);
} }
g_hash_table_iter_init(&iter, widget->properties); g_hash_table_iter_init(&iter, widget->properties);
while (g_hash_table_iter_next(&iter, &key, &value)) { while (g_hash_table_iter_next(&iter, &key, &value)) {
Property *p = (Property *)value; Property *pv = (Property *)value;
rofi_theme_print_property_index(property_name_length, index + 4, p); rofi_theme_print_property_index(property_name_length, index + 4, pv);
} }
printf("%*s}\n", index, ""); printf("%*s}\n", index, "");
g_list_free(list); g_list_free(list);
@ -754,9 +754,9 @@ static int rofi_theme_get_position_inside(Property *p, const widget *widget,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_POSITION, property, FALSE); rofi_theme_find_property(parent, P_POSITION, property, FALSE);
return rofi_theme_get_position_inside(p, widget, property, def); return rofi_theme_get_position_inside(pv, widget->parent, property, def);
} }
return def; return def;
} }
@ -779,9 +779,9 @@ static int rofi_theme_get_integer_inside(Property *p, const widget *widget,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_INTEGER, property, FALSE); rofi_theme_find_property(parent, P_INTEGER, property, FALSE);
return rofi_theme_get_integer_inside(p, widget, property, def); return rofi_theme_get_integer_inside(pv, widget->parent, property, def);
} }
return def; return def;
} }
@ -806,9 +806,10 @@ static RofiDistance rofi_theme_get_distance_inside(Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_PADDING, property, FALSE); rofi_theme_find_property(parent, P_PADDING, property, FALSE);
return rofi_theme_get_distance_inside(p, widget->parent, property, def); return rofi_theme_get_distance_inside(pv, widget->parent, property,
def);
} }
return (RofiDistance){ return (RofiDistance){
.base = {def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, .base = {def, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL},
@ -841,9 +842,9 @@ static int rofi_theme_get_boolean_inside(Property *p, const widget *widget,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_BOOLEAN, property, FALSE); rofi_theme_find_property(parent, P_BOOLEAN, property, FALSE);
return rofi_theme_get_boolean_inside(p, widget, property, def); return rofi_theme_get_boolean_inside(pv, widget->parent, property, def);
} }
return def; return def;
} }
@ -869,9 +870,9 @@ static RofiOrientation rofi_theme_get_orientation_inside(Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_ORIENTATION, property, FALSE); rofi_theme_find_property(parent, P_ORIENTATION, property, FALSE);
return rofi_theme_get_orientation_inside(p, widget, property, def); return rofi_theme_get_orientation_inside(pv, widget->parent, property, def);
} }
return def; return def;
} }
@ -898,9 +899,9 @@ static RofiCursorType rofi_theme_get_cursor_type_inside(Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_CURSOR, property, FALSE); rofi_theme_find_property(parent, P_CURSOR, property, FALSE);
return rofi_theme_get_cursor_type_inside(p, widget, property, def); return rofi_theme_get_cursor_type_inside(pv, widget->parent, property, def);
} }
return def; return def;
} }
@ -926,9 +927,9 @@ static const char *rofi_theme_get_string_inside(Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_STRING, property, FALSE); rofi_theme_find_property(parent, P_STRING, property, FALSE);
return rofi_theme_get_string_inside(p, widget, property, def); return rofi_theme_get_string_inside(pv, widget->parent, property, def);
} }
return def; return def;
} }
@ -944,7 +945,7 @@ const char *rofi_theme_get_string(const widget *widget, const char *property,
Property *p = rofi_theme_find_property(wid, P_STRING, property, FALSE); Property *p = rofi_theme_find_property(wid, P_STRING, property, FALSE);
return rofi_theme_get_string_inside(p, widget, property, def); return rofi_theme_get_string_inside(p, widget, property, def);
} }
static double rofi_theme_get_double_inside(ThemeWidget *wid, Property *p, static double rofi_theme_get_double_inside(const widget *orig, Property *p,
const widget *widget, const widget *widget,
const char *property, double def) { const char *property, double def) {
if (p) { if (p) {
@ -952,39 +953,25 @@ static double rofi_theme_get_double_inside(ThemeWidget *wid, Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_DOUBLE, property, FALSE); rofi_theme_find_property(parent, P_DOUBLE, property, FALSE);
return rofi_theme_get_double_inside(parent, p, widget, property, def); return rofi_theme_get_double_inside(orig, pv, widget, property, def);
} }
return def; return def;
} }
return p->value.f; return p->value.f;
} }
ThemeWidget *wid =
rofi_theme_find_widget(orig->name, widget->state, FALSE);
// Fallback to integer if double is not found. // Fallback to integer if double is not found.
p = rofi_theme_find_property(wid, P_INTEGER, property, FALSE); p = rofi_theme_find_property(wid, P_INTEGER, property, FALSE);
if (p) { return rofi_theme_get_integer_inside(p, widget, property, def);
if (p->type == P_INHERIT) {
if (widget->parent) {
ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p =
rofi_theme_find_property(parent, P_INTEGER, property, FALSE);
return rofi_theme_get_double_inside(parent, p, widget->parent, property,
def);
}
return def;
}
return (double)p->value.i;
}
g_debug("Theme entry: #%s %s property %s unset.", widget->name,
widget->state ? widget->state : "", property);
return def;
} }
double rofi_theme_get_double(const widget *widget, const char *property, double rofi_theme_get_double(const widget *widget, const char *property,
double def) { double def) {
ThemeWidget *wid = rofi_theme_find_widget(widget->name, widget->state, FALSE); ThemeWidget *wid = rofi_theme_find_widget(widget->name, widget->state, FALSE);
Property *p = rofi_theme_find_property(wid, P_DOUBLE, property, FALSE); Property *p = rofi_theme_find_property(wid, P_DOUBLE, property, FALSE);
return rofi_theme_get_double_inside(wid, p, widget, property, def); return rofi_theme_get_double_inside(widget, p, widget, property, def);
} }
static void rofi_theme_get_color_inside(const widget *widget, Property *p, static void rofi_theme_get_color_inside(const widget *widget, Property *p,
const char *property, cairo_t *d) { const char *property, cairo_t *d) {
@ -993,9 +980,9 @@ static void rofi_theme_get_color_inside(const widget *widget, Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_COLOR, property, FALSE); rofi_theme_find_property(parent, P_COLOR, property, FALSE);
rofi_theme_get_color_inside(widget, p, property, d); rofi_theme_get_color_inside(widget->parent, pv, property, d);
} }
return; return;
} }
@ -1021,9 +1008,9 @@ static gboolean rofi_theme_get_image_inside(Property *p, const widget *widget,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_IMAGE, property, FALSE); rofi_theme_find_property(parent, P_IMAGE, property, FALSE);
return rofi_theme_get_image_inside(p, widget, property, d); return rofi_theme_get_image_inside(pv, widget->parent, property, d);
} }
return FALSE; return FALSE;
} }
@ -1133,9 +1120,9 @@ static RofiPadding rofi_theme_get_padding_inside(Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_PADDING, property, FALSE); rofi_theme_find_property(parent, P_PADDING, property, FALSE);
return rofi_theme_get_padding_inside(p, widget, property, pad); return rofi_theme_get_padding_inside(pv, widget->parent, property, pad);
} }
return pad; return pad;
} }
@ -1168,8 +1155,9 @@ static GList *rofi_theme_get_list_inside(Property *p, const widget *widget,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = rofi_theme_find_property(parent, P_LIST, property, FALSE); Property *pv =
return rofi_theme_get_list_inside(p, widget, property, defaults); rofi_theme_find_property(parent, P_LIST, property, FALSE);
return rofi_theme_get_list_inside(pv, widget->parent, property, defaults);
} }
} else if (p->type == P_LIST) { } else if (p->type == P_LIST) {
return g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL); return g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL);
@ -1202,9 +1190,10 @@ rofi_theme_get_highlight_inside(Property *p, widget *widget,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pv =
rofi_theme_find_property(parent, P_HIGHLIGHT, property, FALSE); rofi_theme_find_property(parent, P_HIGHLIGHT, property, FALSE);
return rofi_theme_get_highlight_inside(p, widget->parent, property, th); return rofi_theme_get_highlight_inside(pv, widget->parent, property,
th);
} }
return th; return th;
} }
@ -1311,16 +1300,6 @@ gboolean rofi_theme_is_empty(void) {
if (rofi_theme->properties == NULL && rofi_theme->num_widgets == 0) { if (rofi_theme->properties == NULL && rofi_theme->num_widgets == 0) {
return TRUE; return TRUE;
} }
if (rofi_theme->num_widgets == 3) {
// HACK: check for default added elements.
for (unsigned int i = 0; i < rofi_theme->num_widgets; i++) {
if (strncmp(rofi_theme->widgets[i]->name, "element", 7) != 0) {
return FALSE;
}
}
return TRUE;
}
return FALSE; return FALSE;
} }
@ -1503,9 +1482,9 @@ static gboolean rofi_theme_has_property_inside(Property *p,
if (widget->parent) { if (widget->parent) {
ThemeWidget *parent = ThemeWidget *parent =
rofi_theme_find_widget(widget->parent->name, widget->state, FALSE); rofi_theme_find_widget(widget->parent->name, widget->state, FALSE);
Property *p = Property *pp =
rofi_theme_find_property(parent, P_STRING, property, FALSE); rofi_theme_find_property(parent, P_STRING, property, FALSE);
return rofi_theme_has_property_inside(p, widget, property); return rofi_theme_has_property_inside(pp, widget->parent, property);
} }
return FALSE; return FALSE;
} }

View file

@ -1417,8 +1417,8 @@ void rofi_view_switch_mode(RofiViewState *state, Mode *mode) {
} }
if (state->sidebar_bar) { if (state->sidebar_bar) {
for (unsigned int j = 0; j < state->num_modi; j++) { for (unsigned int j = 0; j < state->num_modi; j++) {
const Mode *mode = rofi_get_mode(j); const Mode *tb_mode = rofi_get_mode(j);
textbox_font(state->modi[j], (mode == state->sw) ? HIGHLIGHT : NORMAL); textbox_font(state->modi[j], (tb_mode == state->sw) ? HIGHLIGHT : NORMAL);
} }
} }
rofi_view_restart(state); rofi_view_restart(state);

View file

@ -407,7 +407,7 @@ static void textbox_draw(widget *wid, cairo_t *draw) {
return; return;
} }
textbox *tb = (textbox *)wid; textbox *tb = (textbox *)wid;
unsigned int offset = ((tb->flags & TB_INDICATOR) ? DOT_OFFSET : 0); unsigned int dot_offset = ((tb->flags & TB_INDICATOR) ? DOT_OFFSET : 0);
if (tb->changed) { if (tb->changed) {
__textbox_update_pango_text(tb); __textbox_update_pango_text(tb);
@ -429,7 +429,7 @@ static void textbox_draw(widget *wid, cairo_t *draw) {
} }
y += top; y += top;
x += offset; x += dot_offset;
if (tb->xalign > 0.001) { if (tb->xalign > 0.001) {
int rem = int rem =

1704
source/xcb.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,15 +0,0 @@
#!/usr/bin/env bash
TOP_DIR=$1
xrdb -retain -load "${TOP_DIR}/doc/old-theme-convert-input.theme"
rofi -config "${TOP_DIR}/doc/old-theme-convert-input.theme" -dump-theme | grep -v "Rofi version" > temp.txt
if ! diff temp.txt "${TOP_DIR}/doc/old-theme-convert-output.rasi" >/dev/null
then
echo "Convert default theme failed"
diff temp.txt "${TOP_DIR}/doc/old-theme-convert-output.rasi"
exit 1
fi
exit "${RETV}"

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
TOP_DIR=$1
rofi -no-config -dump-theme | grep -v "Rofi version" > temp.txt
if ! diff temp.txt "${TOP_DIR}/doc/default_theme.rasi" >/dev/null
then
echo "Dump default theme does not match."
diff temp.txt "${TOP_DIR}/doc/default_theme.rasi"
exit 1
fi
exit "${RETV}"

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
TOP_DIR=$1
rofi -h -config "${TOP_DIR}/doc/test_xr.txt" | awk 'BEGIN{ found=1} /^Global options:/{found=0} {if (found) print }' > help-output.txt
if ! diff help-output.txt "${TOP_DIR}/doc/help-output.txt" >/dev/null
then
diff help-output.txt "${TOP_DIR}/doc/help-output.txt"
echo "Help output does not match."
exit 1
fi
exit "${RETV}"

View file

@ -1,47 +0,0 @@
#!/usr/bin/env bash
tests=(
run_errormsg_test
run_switchdialog_test
run_dmenu_test
run_run_test
run_script_test
run_script_meta_test
run_issue_256
run_issue_275
run_dmenu_empty
run_dmenu_issue_292
run_screenshot_test
run_combi_test
run_regex_test
run_glob_test
run_issue333_test
help_output_test
default_theme_test
convert_old_theme_test
run_dmenu_normal_window_test
run_window_test
)
cd -- "${MESON_BUILD_ROOT}"
mkdir -p test-x-logs
rm -f core
display=200
for test in "${tests[@]}"; do
log_prefix=test-x-logs/${display}
echo -n "Test ${test}: "
${MESON_SOURCE_ROOT}/test/run_test.sh ${display} ${log_prefix} ${MESON_SOURCE_ROOT}/test/${test}.sh ${MESON_BUILD_ROOT} ${MESON_SOURCE_ROOT} &> ${log_prefix}-wrapper.log
ret=$?
if [[ -f core ]]; then
echo "COREDUMP"
echo "bt" | gdb ./rofi core
more ${log_prefix}*.log | cat
exit "${ret}"
elif [[ ${ret} != 0 ]]; then
echo "FAIL"
more ${log_prefix}*.log | cat
exit "${ret}"
fi
echo "PASS"
display=$(( display + 1 ))
done

View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
rofi -show combi -modi combi -combi-modi run,drun &
RPID=$!
# send enter.
sleep 5
xdotool key 't'
sleep 0.4
xdotool key 'r'
sleep 0.4
xdotool key 'u'
sleep 0.4
xdotool key 'e'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,16 +0,0 @@
#!/usr/bin/env bash
rofi -dmenu & </dev/null
RPID=$!
sleep 4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
if [ "${RETV}" -eq 0 ]
then
exit 0
else
exit 1
fi

View file

@ -1,48 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
sleep 1
echo {0..100} | tr " " "\n" | rofi -dmenu -multi-select > output.txt &
RPID=$!
# send enter.
sleep 5
xdotool key '2'
sleep 0.4
xdotool key Shift+Return
#2
xdotool key Shift+Return
#20
xdotool key Shift+Return
#21
xdotool key Shift+Return
#22
xdotool key Shift+Return
#23
xdotool key Shift+Return
#24
xdotool key Shift+Return
#25
xdotool key Shift+Return
#26
xdotool key Shift+Return
#27
xdotool key Shift+Return
#28
xdotool key Shift+Return
#29
xdotool key Shift+Return
#32
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$(tr '\n' ' ' < output.txt)
if [ "${OUTPUT}" != '2 12 20 21 22 23 24 25 26 27 28 29 ' ]
then
echo "Got: '${OUTPUT}' expected '2 12 20 21 22 23 24 25 26 27 28 29 '"
exit 1
fi
echo "${RETV}"
exit "${RETV}"

View file

@ -1,34 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
sleep 1
ulimit -c unlimited
echo -e -n "aap\nnoot\nmies" | rofi -dmenu -normal-window -multi-select > output.txt &
RPID=$!
sleep 4
xdotool getactivewindow windowsize 100% 100%
echo "Window resized"
# send enter.
sleep 1
xdotool key 'Down'
sleep 0.4
xdotool key Shift+Return
xdotool key Shift+Return
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
if [ "${RETV}" == "139" ]
then
echo "thread apply all bt" | gdb rofi core.*
fi
OUTPUT=$( tr '\n' ' ' < output.txt )
if [ "${OUTPUT}" != 'noot mies ' ]
then
echo "Got: '${OUTPUT}' expected 'noot mies '"
exit 1
fi
echo "${RETV}"
exit "${RETV}"

View file

@ -1,26 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
sleep 1
echo -e -n "aap\nnoot\nmies" | rofi -dmenu -multi-select > output.txt &
RPID=$!
# send enter.
sleep 5
xdotool key 'Down'
sleep 0.4
xdotool key Shift+Return
xdotool key Shift+Return
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$( tr '\n' ' ' < output.txt )
if [ "${OUTPUT}" != 'noot mies ' ]
then
echo "Got: '${OUTPUT}' expected 'noot mies '"
exit 1
fi
echo "${RETV}"
exit "${RETV}"

View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
rofi -show drun -modi drun &
RPID=$!
# send enter.
sleep 5
xdotool key 't'
sleep 0.4
xdotool key 'r'
sleep 0.4
xdotool key 'u'
sleep 0.4
xdotool key 'e'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,13 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
sleep 1 && rofi -e "Printing error message" &
RPID=$!
# send enter.
sleep 5 && xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,26 +0,0 @@
#!/usr/bin/env bash
echo -en "nooty\naap\nnoot\nmies" | rofi -matching glob -dmenu > output.txt &
RPID=$!
# send enter.
sleep 5
xdotool key 'n'
sleep 0.4
xdotool key Shift+'8'
sleep 0.4
xdotool key 't'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$(cat output.txt)
if [ "${OUTPUT}" != 'nooty' ]
then
echo "Got: '${OUTPUT}' expected 'nooty'"
exit 1
fi
exit "${RETV}"

View file

@ -1,33 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
rm -f output.txt
sleep 1
echo -e -n "aap\nnoot\nmies" | rofi -dmenu -no-custom -kb-custom-1 F5 -kb-move-front "" -kb-custom-2 "Control+a" > output.txt &
RPID=$!
# send enter.
sleep 5
xdotool key 'q'
sleep 0.4
xdotool key Return
sleep 0.4
xdotool key F5
sleep 0.4
xdotool key "Control+a"
sleep 0.4
xdotool key Escape
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$(tr '\n' ' ' < output.txt)
if [ "${OUTPUT}" != '' ]
then
echo "Got: '${OUTPUT}' expected nothing"
exit 1
fi
if [ "${RETV}" != 1 ]
then
exit 1
fi

View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
rofi -show window -modi window &
RPID=$!
# send enter.
sleep 5
xdotool key 't'
sleep 0.4
xdotool key 'r'
sleep 0.4
xdotool key 'u'
sleep 0.4
xdotool key 'e'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,24 +0,0 @@
#!/usr/bin/env bash
echo -e "aap\nnoot\nmies" | rofi -dmenu &
RPID=$!
# send enter.
sleep 5
xdotool key 't'
sleep 0.4
xdotool key 'r'
sleep 0.4
xdotool key 'u'
sleep 0.4
xdotool key 'e'
sleep 0.4
xdotool key End
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,32 +0,0 @@
#!/usr/bin/env bash
echo -en "nooty\naap\nnoot\nmies" | rofi -matching regex -dmenu > output.txt &
RPID=$!
# send enter.
sleep 5
xdotool key Shift+'6'
sleep 0.4
xdotool key 'n'
sleep 0.4
xdotool key 'o'
sleep 0.4
xdotool key 'o'
sleep 0.4
xdotool key 't'
sleep 0.4
xdotool key Shift+'4'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$(cat output.txt)
if [ "${OUTPUT}" != 'noot' ]
then
echo "Got: '${OUTPUT}' expected 'noot'"
exit 1
fi
exit "${RETV}"

View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
rofi -show run &
RPID=$!
# send enter.
sleep 5
xdotool key 't'
sleep 0.4
xdotool key 'r'
sleep 0.4
xdotool key 'u'
sleep 0.4
xdotool key 'e'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,28 +0,0 @@
#!/usr/bin/env bash
export ROFI_PNG_OUTPUT=out.png
rofi -show run &
RPID=$!
# send enter.
sleep 5
xdotool key 't'
sleep 0.4
xdotool key 'r'
sleep 0.4
xdotool key 'u'
sleep 0.4
xdotool key Alt+Shift+s
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
if [ ! -f out.png ]
then
echo "Failed to create screenshot"
exit 1
fi
exit "${RETV}"

View file

@ -1,26 +0,0 @@
#!/usr/bin/env bash
SP=$(readlink -f "$0")
DIR=$(dirname "$SP")
echo "$DIR/test_script.sh"
# wait till it is up, run rofi with error message
sleep 1
rofi -modi "custom:$DIR/test_script.sh" -show custom &
RPID=$!
# send enter.
sleep 5
xdotool key 'z'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$( tr '\n' ' ' < output.txt )
echo "${OUTPUT}"
if [ "${OUTPUT}" != 'mies ' ]
then
exit 1
fi
exit "${RETV}"

View file

@ -1,26 +0,0 @@
#!/usr/bin/env bash
SP=$(readlink -f "$0")
DIR=$(dirname "$SP")
echo "$DIR/test_script.sh"
# wait till it is up, run rofi with error message
sleep 1
rofi -modi "custom:$DIR/test_script.sh" -show custom &
RPID=$!
# send enter.
sleep 5
xdotool key 'Down'
sleep 0.4
xdotool key Return
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
OUTPUT=$( tr '\n' ' ' < output.txt )
echo "${OUTPUT}"
if [ "${OUTPUT}" != 'noot ' ]
then
exit 1
fi
exit "${RETV}"

View file

@ -1,23 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
sleep 1 && rofi -show run -modi run &
RPID=$!
# send enter.
sleep 5
xdotool key 'shift+slash'
sleep 0.4
xdotool key 'shift+slash'
sleep 0.4
xdotool key 'shift+slash'
sleep 0.4
xdotool key Escape
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
sleep 1
exit "${RETV}"

View file

@ -1,58 +0,0 @@
#!/usr/bin/env bash
XPID=
FPID=
create_fake_x()
{
export DISPLAY=":$1"
echo -n "Starting fake X for display ${DISPLAY}: "
Xvfb -nolisten tcp +extension XINERAMA +xinerama -screen 0 1280x1024x24 "${DISPLAY}" &>$2-server.log &
XPID=$!
echo "pid ${XPID}"
sleep 1
if [ -x "$(which fluxbox 2>/dev/null)" ]; then
echo -n "Starting fluxbox for display ${DISPLAY}: "
timeout -k 30s 30s fluxbox &>$2-fluxbox.log &
FPID=$!
echo "pid ${FPID}"
sleep 1
fi
}
destroy_fake_x()
{
if [ -n "${XPID}" ]
then
if [ -n "${FPID}" ]; then
echo -n "Stopping fluxbox for display ${DISPLAY} (pid ${FPID}): "
if kill "${FPID}" &>$1-kill-fluxbox.log; then
echo -n " killed... "
wait "${FPID}" &>$1-wait-fluxbox.log
echo "stopped"
else
echo -n " failed to kill"
fi
fi
echo -n "Stopping fake X for display ${DISPLAY} (pid ${XPID}): "
if kill "${XPID}" &>$1-kill-X.log; then
echo -n " killed... "
wait "${XPID}" &>$1-wait-X.log
echo "stopped"
else
echo -n " failed to kill"
fi
fi
}
if [ -n "$4" ]
then
export PATH=$4:$PATH
fi
create_fake_x "$1" "$2"
"$3" "$5" &> "$2-test.log"
RES=$?
destroy_fake_x "$2"
exit "${RES}"

View file

@ -1,46 +0,0 @@
#!/usr/bin/env bash
# wait till it is up, run rofi with error message
sleep 1
xterm -T MonkeySee sh &
XPID=$!
echo "Started MonkeySee xterm: pid ${XPID}"
sleep 1
xterm -T TermUnwanted sh &
TPID=$!
echo "Started TermUnwanted xterm: pid ${TPID}"
sleep 1
rofi -modi window -show window > output.txt &
RPID=$!
echo "Started rofi: pid ${RPID}"
# send enter.
sleep 5
xdotool type 'MonkeySee'
sleep 0.4
xdotool key Return
sleep 1
xdotool key Ctrl+d
sleep 1
echo -n "Killing TermUnwanted: "
if kill "${TPID}"; then
echo "done"
wait "${TPID}"
fi
if ps -q "${XPID}" # pgrep -u $USER xterm
then
echo "Found remaining xterms: $(pgrep -u "$USER" xterm)"
kill "${XPID}"
fi
if ps -q "${RPID}"
then
echo "Rofi still running"
kill "${RPID}"
exit 1
fi
# Get result, kill xvfb
wait "${RPID}"
RETV=$?
exit "${RETV}"

View file

@ -1,10 +0,0 @@
#!/usr/bin/env bash
if [ -z "$1" ]
then
echo "aap"
echo "noot"
echo -ne "mies\0meta\x1fzoom\n"
else
echo "$1" > output.txt
fi

View file

@ -125,7 +125,7 @@ textbox-prompt-sep {
text-color: @normal-foreground; text-color: @normal-foreground;
margin: 0 0.3em 0 0; margin: 0 0.3em 0 0;
} }
element-text { element-text, element-icon {
background-color: inherit; background-color: inherit;
text-color: inherit; text-color: inherit;
} }

View file

@ -57,7 +57,7 @@ listview, inputbar, message {
border-radius: 10px; border-radius: 10px;
background-color: black/70%; background-color: black/70%;
columns: 3; columns: 4;
lines: 4; lines: 4;
} }
listview { listview {
@ -68,12 +68,12 @@ listview {
element { element {
border: 0; border: 0;
padding: 0.25em; padding: 10px;
font: "Mono 8"; font: "Mono 8";
orientation: vertical; orientation: vertical;
} }
element-icon { element-icon {
size: 3em; size: 6em;
} }
element selected { element selected {