Compare commits

...

10 commits

Author SHA1 Message Date
WanderingPenwing 902e1bf3f9 cleaned up 2024-08-05 15:42:39 +02:00
WanderingPenwing cb1b6037e6 modified config.def 2024-08-05 15:36:38 +02:00
WanderingPenwing d40b6fa723 force config color 2024-08-04 11:40:07 +02:00
WanderingPenwing 9c41ea8dcc my config 2024-08-04 11:03:06 +02:00
NRK 0ddf494437 introduce parse_optional_no() 2024-08-02 11:11:44 +00:00
NRK c61b84975d add --bar to enable statusbar
ref: https://codeberg.org/nsxiv/nsxiv/issues/404
2024-08-02 11:11:42 +00:00
NRK 55d60319db allow disabling animation playback via -A 0
ref: https://codeberg.org/nsxiv/nsxiv/issues/404
2024-08-02 11:08:47 +00:00
NRK 11558c9fcf allow disabling thumbnail mode via --thumbnail=no
the short opt -t does not accept optional argument since it'd
break short option chaining.

e.g `nsxiv -tp` currently works as `nsxiv -t -p` but if `-t`
accepted optional argument then it'd stop working since "p" will
be interpreted as argument to `-t` instead of being a flag.

ref: https://codeberg.org/nsxiv/nsxiv/issues/404
2024-08-02 11:08:44 +00:00
André Marçais 3408bbcdda print help to stderr on usage error (#510)
`print_usage` is called in two cases:

1) when `-h` is given on the command line.
2) when there is a usage error.

In the first case, the help message should go to stdout. In the second case,
it is an error, and should go to stderr.

Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/510
Reviewed-by: NRK <nrk@disroot.org>
Co-authored-by: André Marçais <pex@marcais.net>
Co-committed-by: André Marçais <pex@marcais.net>
2024-08-02 11:05:05 +00:00
NRK 9406e7ea7c statusbar: print ellipsis when text is truncated (#501)
currently, there's no feedback on when the statusbar text is
getting truncated due to insufficient space. this prints an
ellipsis if the text wouldn't be able to fit inside the given
width to indicate truncation.

Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/501
Reviewed-by: eylles <eylles@noreply.codeberg.org>
2024-06-27 15:54:08 +00:00
31 changed files with 95 additions and 2077 deletions

212
README.md
View file

@ -1,199 +1,12 @@
[![nsxiv](https://codeberg.org/nsxiv/pages/raw/branch/master/img/logo.png)](https://codeberg.org/nsxiv/nsxiv) [![nsxiv](https://codeberg.org/nsxiv/pages/raw/branch/master/img/logo.png)](https://codeberg.org/nsxiv/nsxiv)
[![Codeberg](https://img.shields.io/badge/Hosted_at-Codeberg-%232185D0?style=flat-square&logo=CodeBerg)](https://codeberg.org/nsxiv/nsxiv)
[![tags](https://img.shields.io/github/v/tag/nsxiv/nsxiv?style=flat-square)](https://codeberg.org/nsxiv/nsxiv/tags)
[![license](https://img.shields.io/badge/license-GPL--2.0%2B-lightgreen?style=flat-square)](https://codeberg.org/nsxiv/nsxiv/src/branch/master/LICENSE) [![license](https://img.shields.io/badge/license-GPL--2.0%2B-lightgreen?style=flat-square)](https://codeberg.org/nsxiv/nsxiv/src/branch/master/LICENSE)
[![loc](https://img.shields.io/tokei/lines/github/nsxiv/nsxiv?color=red&style=flat-square)](https://codeberg.org/nsxiv/nsxiv)
**Neo (or New or Not) Simple (or Small or Suckless) X Image Viewer** **Zeniba Image Viewer**
-------------------------------------------------------------------- --------------------------------------------------------------------
nsxiv is a fork of the now-unmaintained [sxiv](https://github.com/xyb3rt/sxiv) fork of the famous [nsxiv](https://codeberg.org/nsxiv/nsxiv)
with the purpose of being a (mostly) drop-in replacement for sxiv, maintaining its
interface and adding simple, sensible features. nsxiv is free software licensed
under GPL-2.0-or-later and aims to be easy to modify and customize.
Please file a bug report if something does not work as documented or expected on
[Codeberg] after making sure you are using the latest release. If you're looking
to migrate from `sxiv`, see [MIGRATION]. Contributions are welcome, see
[CONTRIBUTING] to get started.
[Codeberg]: https://codeberg.org/nsxiv/nsxiv/issues/new
[CONTRIBUTING]: etc/CONTRIBUTING.md#contribution-guideline
[MIGRATION]: etc/MIGRATION.md
Features
--------
* Basic image operations like zooming, panning, rotating
* Basic support for animated/multi-frame images (**requires Imlib2 v1.8.0 or above**)
* Thumbnail mode: grid of selectable previews of all images
* Ability to cache thumbnails for fast re-loading
* Automatically refreshing modified images
* Customizable keyboard and mouse mappings via `config.h`
* Scriptability via `key-handler`
* Displaying image information in status bar via `image-info` & `thumb-info`
* Customizable window title via `win-title`
Screenshots
-----------
**Image mode with default colors:**
![Image](https://codeberg.org/nsxiv/pages/raw/branch/master/img/image.png "Image mode")
**Thumbnail mode with custom colors:**
![Thumb](https://codeberg.org/nsxiv/pages/raw/branch/master/img/thumb.png "Thumb mode")
Installing via package manager
------------------------------
<a href="https://repology.org/project/nsxiv/versions">
<img align="right" width="192" src="https://repology.org/badge/vertical-allrepos/nsxiv.svg">
</a>
nsxiv is available on the following distributions/repositories. If you don't see
your distro listed here, either contact your distro's package maintainer or
consider packaging it yourself and adding it to the respective community repo.
Dependencies
------------
nsxiv requires the following software to be installed:
* X11
* Imlib2 (built with X11 support)
The following dependencies are optional:
* `inotify`<sup>\*</sup>: Used for auto-reloading images on change.
Disabled via `HAVE_INOTIFY=0`.
* `libXft`, `freetype2`, `fontconfig`: Used for the status bar.
Disabled via `HAVE_LIBFONTS=0`.
* `libexif`: Used for auto-orientation and exif thumbnails.
Disable via `HAVE_LIBEXIF=0`.
Please make sure to install the corresponding development packages in case that
you want to build nsxiv on a distribution with separate runtime and development
packages (e.g. \*-dev on Debian).
\* [inotify][] is a Linux-specific API for monitoring filesystem changes.
It's not natively available on `*BSD` systems but can be enabled via
installing and linking against [libinotify-kqueue][].
[inotify]: https://www.man7.org/linux/man-pages/man7/inotify.7.html
[libinotify-kqueue]: https://github.com/libinotify-kqueue/libinotify-kqueue
Building
--------
nsxiv is built using the commands:
$ make
You can pass `HAVE_X=0` to `make` to disable an optional dependency.
For example:
$ make HAVE_LIBEXIF=0
will disable `libexif` support. Alternatively they can be disabled via editing
`config.mk`. `OPT_DEP_DEFAULT=0` can be used to disable all optional
dependencies.
Installing nsxiv:
# make install
Installing desktop entry:
# make install-desktop
Installing icons:
# make install-icon
Installing all of the above:
# make install-all
Please note, that these requires root privileges.
By default, nsxiv is installed using the prefix `/usr/local`, so the full path
of the executable will be `/usr/local/bin/nsxiv`, the `.desktop` entry will be
`/usr/local/share/applications/nsxiv.desktop` and the icon path will be
`/usr/local/share/icons/hicolor/{size}/apps/nsxiv.png`.
You can install nsxiv into a directory of your choice by changing this command to:
$ make PREFIX="/your/dir" install
Example scripts are installed using `EGPREFIX` which defaults to
`/usr/local/share/doc/nsxiv/examples`. You can change `EGPREFIX` the same way
you can change `PREFIX` shown above.
The build-time specific settings of nsxiv can be found in the file *config.h*.
Please check and change them, so that they fit your needs.
If the file *config.h* does not already exist, then you have to create it with
the following command:
$ make config.h
Usage
-----
Refer to the man-page for the documentation:
$ man nsxiv
You may also view the man-page [online](https://nsxiv.codeberg.page/man/).
However, note that the online man-page might not accurately represent your local
copy.
F.A.Q.
------
* Can I open remote urls with nsxiv? <br>
Yes, see [nsxiv-url](https://codeberg.org/nsxiv/nsxiv-extra/src/branch/master/scripts/nsxiv-url)
* Can I open all the images in a directory? <br>
Yes, see [nsxiv-rifle](https://codeberg.org/nsxiv/nsxiv-extra/src/branch/master/scripts/nsxiv-rifle)
* Can I set default arguments for nsxiv? <br>
Yes, see [nsxiv-env](https://codeberg.org/nsxiv/nsxiv-extra/src/branch/master/scripts/nsxiv-env)
* Can I pipe images into nsxiv? <br>
Yes, see [nsxiv-pipe](https://codeberg.org/nsxiv/nsxiv-extra/src/branch/master/scripts/nsxiv-pipe)
You may also wish to see the [known issues](https://codeberg.org/nsxiv/nsxiv/issues/242).
Customization
-------------
The main method of customizing nsxiv is by setting values for the variables in *config.h*,
or by using Xresources as explained in the manual. If these options are not sufficient,
you may implement your own features by following
[this guide](https://codeberg.org/nsxiv/nsxiv-extra/src/branch/master/CUSTOMIZATION.md).
Due to our limited [project scope](etc/CONTRIBUTING.md#project-scope), certain features or
customization cannot be merged into nsxiv mainline. Following the spirit of suckless
software, we host the [nsxiv-extra](https://codeberg.org/nsxiv/nsxiv-extra) repo where users
are free to submit whatever patches or scripts they wish.
If you think your custom features can be beneficial for the general user base and is within
our project scope, please submit it as a pull request on this repository, then we *may*
merge it to mainline.
Description on how to use or submit patches can be found on
nsxiv-extra's [README](https://codeberg.org/nsxiv/nsxiv-extra).
to configure it juust the way I like it
Download Download
-------- --------
@ -203,22 +16,3 @@ on Codeberg or get a copy using git with the following command:
$ git clone https://codeberg.org/nsxiv/nsxiv.git $ git clone https://codeberg.org/nsxiv/nsxiv.git
You can view the changelog [here](etc/CHANGELOG.md)
Similar projects
----------------
If nsxiv isn't able to fit your needs, check out the image viewer section of
**[suckless rocks](https://suckless.org/rocks)** to find other minimal image
viewers to try out.
Below are a couple other lesser known projects not listed in suckless rocks.
* [MAGE](https://codeberg.org/explosion-mental/mage):
A smaller/more-suckless version of sxiv.
* [div](https://codeberg.org/TAAPArthur/div):
Minimal and extensive, aimed at C devs willing to build their own features.
* [mpv-image-viewer](https://github.com/occivink/mpv-image-viewer):
Lua script to turn mpv into an image viewer. Supports thumbnails via
[mpv-gallery-view](https://github.com/occivink/mpv-gallery-view).

View file

@ -7,13 +7,13 @@ static const int WIN_HEIGHT = 600;
/* colors and font can be overwritten via X resource properties. /* colors and font can be overwritten via X resource properties.
* See nsxiv(1), X(7) section Resources and xrdb(1) for more information. * See nsxiv(1), X(7) section Resources and xrdb(1) for more information.
* X resource value (NULL == default) */ * X resource value (NULL == default) */
static const char *WIN_BG[] = { "Nsxiv.window.background", "white" }; static const char *WIN_BG[] = { "Nsxiv.window.background", "#222222" };
static const char *WIN_FG[] = { "Nsxiv.window.foreground", "black" }; static const char *WIN_FG[] = { "Nsxiv.window.foreground", "#cccccc" };
static const char *MARK_FG[] = { "Nsxiv.mark.foreground", NULL }; static const char *MARK_FG[] = { "Nsxiv.mark.foreground", NULL };
#if HAVE_LIBFONTS #if HAVE_LIBFONTS
static const char *BAR_BG[] = { "Nsxiv.bar.background", NULL }; static const char *BAR_BG[] = { "Nsxiv.bar.background", NULL };
static const char *BAR_FG[] = { "Nsxiv.bar.foreground", NULL }; static const char *BAR_FG[] = { "Nsxiv.bar.foreground", NULL };
static const char *BAR_FONT[] = { "Nsxiv.bar.font", "monospace-8" }; static const char *BAR_FONT[] = { "Nsxiv.bar.font", "Mononoki Nerd Font:size=16" };
/* if true, statusbar appears on top of the window */ /* if true, statusbar appears on top of the window */
static const bool TOP_STATUSBAR = false; static const bool TOP_STATUSBAR = false;
@ -53,8 +53,8 @@ static const int PAN_FRACTION = 5;
* NOTE: higher cache size means better image reloading performance, but also * NOTE: higher cache size means better image reloading performance, but also
* higher memory usage. * higher memory usage.
*/ */
static const int CACHE_SIZE_MEM_PERCENTAGE = 3; /* use 3% of total memory for cache */ static const int CACHE_SIZE_MEM_PERCENTAGE = 2; /* use 3% of total memory for cache */
static const int CACHE_SIZE_LIMIT = 256 * 1024 * 1024; /* but not above 256MiB */ static const int CACHE_SIZE_LIMIT = 200 * 1024 * 1024; /* but not above 256MiB */
static const int CACHE_SIZE_FALLBACK = 32 * 1024 * 1024; /* fallback to 32MiB if we can't determine total memory */ static const int CACHE_SIZE_FALLBACK = 32 * 1024 * 1024; /* fallback to 32MiB if we can't determine total memory */
#endif #endif

View file

@ -1,82 +0,0 @@
# clang-format doesn't dictate the project's code style and can mess up a
# couple edge cases. However it comes quite close and can be used for fixing
# most style issues automatically on new changes via `git-clang-format`.
---
Standard: c++03
ColumnLimit: 0
AccessModifierOffset: -8
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 8
IndentWrappedFunctionNames: false
NamespaceIndentation: None
TabWidth: 8
UseTab: AlignWithSpaces
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: false
AlignOperands: true
AlignTrailingComments: false
DerivePointerAlignment: true
PointerAlignment: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterControlStatement: MultiLine
AfterEnum: false
AfterExternBlock: false
AfterFunction: true
AfterStruct: false
AfterUnion: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
BreakBeforeBinaryOperators: None
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: BeforeComma
BreakConstructorInitializersBeforeComma: false
BreakStringLiterals: true
Cpp11BracedListStyle: false
MaxEmptyLinesToKeep: 1
ReflowComments: false
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
...

View file

@ -1,499 +0,0 @@
nsxiv - Changelog
-----------------
**[git](https://codeberg.org/nsxiv/nsxiv.git)**
Changes will only be documented on stable releases. If you're on git/master then
there may be more changes. Please use `git log` to view them.
- - -
**[v32](https://codeberg.org/nsxiv/nsxiv/archive/v32.tar.gz)**
*(October 01, 2023)*
* Changes:
* Removed legacy multi-frame loaders. Animated image support now requires
Imlib2 v1.8.0 or above.
* Move loading/caching messages to right side bar [#446]
* Set a default delay if delay is 0 in a multi-frame image [#445]
* `config.mk`: default to `-O2` [#435]
* `config.mk` no longer explicitly sets `CC` to `c99` [#455]
* Assertions are now opt-in and requires explicitly defining `DEBUG` [#447]
* Added:
* Added a pick-quit key-binding [#432]
* Ability to configure Xresources class name in `config.h` [#427]
* `--version` output now also includes compiled-in feature list [#462]
* Document handling of empty X resources values [#428]
* Experimental flag `--bg-cache` to generate thumbnail cache in a background
process [#438]
* Fixes:
* Changing brightness/contrast on multi-frame images [#440]
* Brightness keybindings on manpage [#467]
* Various autoreload bugs [#437], [#459], [#460]
* `*-info` scripts not updating when selecting thumbnail with mouse [#477]
* Updated openbsd configuration in `config.mk` [#453]
* Memory leak in `win_draw_bar` [#444]
* Thumbnail leak when removing the last file [#423]
[#423]: https://codeberg.org/nsxiv/nsxiv/pulls/423
[#427]: https://codeberg.org/nsxiv/nsxiv/pulls/427
[#428]: https://codeberg.org/nsxiv/nsxiv/pulls/428
[#432]: https://codeberg.org/nsxiv/nsxiv/pulls/432
[#435]: https://codeberg.org/nsxiv/nsxiv/pulls/435
[#437]: https://codeberg.org/nsxiv/nsxiv/pulls/437
[#438]: https://codeberg.org/nsxiv/nsxiv/pulls/438
[#440]: https://codeberg.org/nsxiv/nsxiv/pulls/440
[#444]: https://codeberg.org/nsxiv/nsxiv/pulls/444
[#445]: https://codeberg.org/nsxiv/nsxiv/pulls/445
[#446]: https://codeberg.org/nsxiv/nsxiv/pulls/446
[#447]: https://codeberg.org/nsxiv/nsxiv/pulls/447
[#453]: https://codeberg.org/nsxiv/nsxiv/pulls/453
[#455]: https://codeberg.org/nsxiv/nsxiv/pulls/455
[#459]: https://codeberg.org/nsxiv/nsxiv/pulls/459
[#460]: https://codeberg.org/nsxiv/nsxiv/pulls/460
[#462]: https://codeberg.org/nsxiv/nsxiv/pulls/462
[#467]: https://codeberg.org/nsxiv/nsxiv/pulls/467
[#477]: https://codeberg.org/nsxiv/nsxiv/pulls/477
- - -
**[v31](https://codeberg.org/nsxiv/nsxiv/archive/v31.tar.gz)**
*(January 28, 2023)*
* Changes:
* Uncritical files moved to `etc/`. [#350]
* Empty Xresource entry will now be ignored. [#340]
* `win-title` will be read in a non-blocking manner. [#314]
* Added:
* Support for multi-frame images via `Imlib2`. [#373]
* Support for long-opts. [#332]
* Cli flag `--anti-alias` to enable/disable anti-aliasing. [#361]
* Cli flag `--alpha-layer` to enable/disable checkerboard background. [#408]
* Accept directory via stdin (-i) [#383]
* Support for modifying brightness and contrast [#396]
* Fixes:
* Build failure when `_SC_PHYS_PAGES` is not defined. [#334]
* Various statusbar issues. [#353],[#341]
* Crashes due to faulty signal-handler. [#411]
* Potential memory leak in `r_readdir()`. [#319]
* Potentially printing incorrect error message. [#321]
* Wrong slideshow length on animated webp. [#381]
* Document missing <kbd>Ctrl+6</kbd> binding in the manpage. [#347]
[#314]: https://codeberg.org/nsxiv/nsxiv/pulls/314
[#319]: https://codeberg.org/nsxiv/nsxiv/pulls/319
[#321]: https://codeberg.org/nsxiv/nsxiv/pulls/321
[#332]: https://codeberg.org/nsxiv/nsxiv/pulls/332
[#334]: https://codeberg.org/nsxiv/nsxiv/pulls/334
[#340]: https://codeberg.org/nsxiv/nsxiv/pulls/340
[#341]: https://codeberg.org/nsxiv/nsxiv/pulls/341
[#347]: https://codeberg.org/nsxiv/nsxiv/pulls/347
[#350]: https://codeberg.org/nsxiv/nsxiv/pulls/350
[#353]: https://codeberg.org/nsxiv/nsxiv/pulls/353
[#361]: https://codeberg.org/nsxiv/nsxiv/pulls/361
[#373]: https://codeberg.org/nsxiv/nsxiv/pulls/373
[#381]: https://codeberg.org/nsxiv/nsxiv/pulls/381
[#383]: https://codeberg.org/nsxiv/nsxiv/pulls/383
[#396]: https://codeberg.org/nsxiv/nsxiv/pulls/396
[#408]: https://codeberg.org/nsxiv/nsxiv/pulls/408
[#411]: https://codeberg.org/nsxiv/nsxiv/pulls/411
- - -
***SPECIAL NOTE***: Due to [this incident](https://codeberg.org/nsxiv/nsxiv-tmp/issues/1)
we have moved development over to [Codeberg](https://codeberg.org/nsxiv/nsxiv).
A lot of the references *below* may now be 404 on GitHub. Any threads which
survived the wipe have been migrated over to [nsxiv-record]. All of the
references *above* can be found on the new main nsxiv repository on Codeberg.
[nsxiv-record]: https://codeberg.org/nsxiv/nsxiv-record/
- - -
**[v30](https://codeberg.org/nsxiv/nsxiv/archive/v30.tar.gz)**
*(June 15, 2022)*
* Changes:
* Development and main repository moved over to Codeberg.
See the special note above for more info.
* `autoreload_{inotify,nop}.c` merged into a single file, `autoreload.c`. [#263]
* Moved all configuration related macros to `config.mk`. [#264]
* `win-title` is now called only when there's change rather than being called
on each redraw. [#266]
* Added:
* Added more mimetypes to the `.desktop` entry. [#260]
* Added `thumb-info` for customizing the statusbar in thumbnail-mode. [#265]
* Added comments for building on OpenBSD. [#264]
* Fixes:
* "Too many open file" error due to not closing the win-title script. [#245]
* `-f` now directly starts in fullscreen mode rather than opening a normal
window and then going fullscreen. [#251]
* Broken slideshow on slow systems or fast animations. [#282]
* Memory leak when removing an image in thumbnail mode. [#247]
* Correctly setting `_NET_WM_PID`. [#251]
* Don't override statusbar if info script doesn't exist. [#271]
* Potential misbehavior regarding font. [#250]
[#245]: https://codeberg.org/nsxiv/nsxiv-record/pulls/245
[#247]: https://codeberg.org/nsxiv/nsxiv-record/pulls/247
[#250]: https://codeberg.org/nsxiv/nsxiv-record/pulls/250
[#251]: https://codeberg.org/nsxiv/nsxiv-record/pulls/251
[#263]: https://codeberg.org/nsxiv/nsxiv-record/pulls/263
[#264]: https://codeberg.org/nsxiv/nsxiv-record/pulls/264
[#260]: https://codeberg.org/nsxiv/nsxiv-record/pulls/260
[#264]: https://codeberg.org/nsxiv/nsxiv-record/pulls/264
[#265]: https://codeberg.org/nsxiv/nsxiv-record/pulls/265
[#266]: https://codeberg.org/nsxiv/nsxiv-record/pulls/266
[#271]: https://codeberg.org/nsxiv/nsxiv-record/pulls/271
[#282]: https://codeberg.org/nsxiv/nsxiv-record/pulls/282
- - -
**[v29](https://github.com/nsxiv/nsxiv/archive/v29.tar.gz)**
*(March 03, 2022)*
* Changes:
* Window title is now customizable via `win-title`, cli flag `-T` and related
config.h options are removed. See `WINDOW TITLE` section of the manpage for
more info. [#213]
* Imlib2 cache size is now set based on total memory percentage, by default
set to 3%. [#184]
* Removed some non-POSIX extensions in the Makefile. [#225]
* Added:
* Ability to customize thumbnail mode mouse-bindings via `config.h`. [#167]
* Option to set statusbar position to top via `config.h`. [#231]
* New keybinding <kbd>z</kbd> to scroll to center. [#203]
* Fixes:
* Manpage cleanup: avoid confusing wording and document thumbnail mode
mouse-bindings. [#186]
* Wrong jpeg exif orientation with Imlib2 v1.7.5 (and above). [#188]
* Animation slowdown when zoomed in. [#200]
* Reset statusbar after failed keyhandler. [#191]
* Window title not working on certain WMs. [#234]
* Various compiler warnings. [#197]
[#167]: https://codeberg.org/nsxiv/nsxiv-record/pulls/167
[#184]: https://codeberg.org/nsxiv/nsxiv-record/pulls/184
[#186]: https://codeberg.org/nsxiv/nsxiv-record/pulls/186
[#188]: https://codeberg.org/nsxiv/nsxiv-record/pulls/188
[#191]: https://codeberg.org/nsxiv/nsxiv-record/pulls/191
[#197]: https://codeberg.org/nsxiv/nsxiv-record/pulls/197
[#200]: https://codeberg.org/nsxiv/nsxiv-record/pulls/200
[#203]: https://codeberg.org/nsxiv/nsxiv-record/pulls/203
[#213]: https://codeberg.org/nsxiv/nsxiv-record/pulls/213
[#225]: https://codeberg.org/nsxiv/nsxiv-record/pulls/225
[#231]: https://codeberg.org/nsxiv/nsxiv-record/pulls/231
[#234]: https://codeberg.org/nsxiv/nsxiv-record/pulls/234
- - -
**[v28](https://github.com/nsxiv/nsxiv/archive/v28.tar.gz)**
*(December 12, 2021)*
* Changes:
* Statusbar made optional via `HAVE_LIBFONTS`. [#95]
* Remove library auto-detection, use `OPT_DEP_DEFAULT` instead. [#71]
* Example scripts will now be installed into `EGPREFIX`
(`$(PREFIX)/share/doc/nsxiv/examples` by default). See README for more
info. [#86]
* Added:
* Animated webp support (optional via `HAVE_LIBWEBP`). [#20]
* New mouse-binding <kbd>Ctrl-Button1</kbd> for relative drag. [#117]
* Ability to configure colors and fonts in `config.h`. [#115]
* Ability to configure navigation width area in `config.h`. [#155]
* Ability to customize the set of modifiers used when processing keybindings
in `config.h` via `USED_MODMASK`. [#150]
* Ability to configure Imlib2's cache size for better image (re)loading
performance in `config.h`. [#171]
* Cli flag `-0` for sending null-seperated file-list to standard out (`-o`),
and key-handler and receiving null-seperated file-list via stdin (`-i`).
[#68],[#141],[#164]
* Export environment variable `NSXIV_USING_NULL` to key-handler. [#164]
* Embed new nsxiv icon. [#163]
* `make install-icon` to install icons. [#80],[#96]
* `make install-desktop` to install .desktop entry. [#80],[#96]
* `make install-all` to install everything. [#80],[#96]
* Configurable `KEYHANDLER_ABORT` in `config.h`. [#91],[#172]
* Statusbar message upon key-handler activation. [#98]
* Ability to write custom C functions in `config.h` and use them via
keybindings. [#76]
* Fixes:
* Not able to use `KEYHANDLER_ABORT` key (<kbd>Escape</kbd> by default) in
regular keybindings. [#91]
* Memory leak related to Xresources. [#134]
* Memory leak in gif loader. [#165]
* Better handle gif colormap and prevent out-of-bound access. [#165]
* Prevent crash when zooming out in very small images. [#178]
* Removed non-POSIX commands and extensions from `Makefile`. [#71]
* Regression where nsxiv wouldn't run on non-TrueColor X server. [#114]
* Wrong comments in `config.h` and description in `manpage`.
[#105],[#106],[#152]
[#20]: https://codeberg.org/nsxiv/nsxiv-record/pulls/20
[#68]: https://codeberg.org/nsxiv/nsxiv-record/pulls/68
[#71]: https://codeberg.org/nsxiv/nsxiv-record/pulls/71
[#76]: https://codeberg.org/nsxiv/nsxiv-record/pulls/76
[#80]: https://codeberg.org/nsxiv/nsxiv-record/pulls/80
[#86]: https://codeberg.org/nsxiv/nsxiv-record/pulls/86
[#91]: https://codeberg.org/nsxiv/nsxiv-record/pulls/91
[#95]: https://codeberg.org/nsxiv/nsxiv-record/pulls/95
[#96]: https://codeberg.org/nsxiv/nsxiv-record/pulls/96
[#98]: https://codeberg.org/nsxiv/nsxiv-record/pulls/98
[#105]: https://codeberg.org/nsxiv/nsxiv-record/pulls/105
[#106]: https://codeberg.org/nsxiv/nsxiv-record/pulls/106
[#114]: https://codeberg.org/nsxiv/nsxiv-record/pulls/114
[#115]: https://codeberg.org/nsxiv/nsxiv-record/pulls/115
[#117]: https://codeberg.org/nsxiv/nsxiv-record/pulls/117
[#134]: https://codeberg.org/nsxiv/nsxiv-record/pulls/134
[#141]: https://codeberg.org/nsxiv/nsxiv-record/pulls/141
[#150]: https://codeberg.org/nsxiv/nsxiv-record/pulls/150
[#152]: https://codeberg.org/nsxiv/nsxiv-record/pulls/152
[#155]: https://codeberg.org/nsxiv/nsxiv-record/pulls/155
[#163]: https://codeberg.org/nsxiv/nsxiv-record/pulls/163
[#164]: https://codeberg.org/nsxiv/nsxiv-record/pulls/164
[#165]: https://codeberg.org/nsxiv/nsxiv-record/pulls/165
[#171]: https://codeberg.org/nsxiv/nsxiv-record/pulls/171
[#172]: https://codeberg.org/nsxiv/nsxiv-record/pulls/172
[#178]: https://codeberg.org/nsxiv/nsxiv-record/pulls/178
- - -
**[v27.1](https://github.com/nsxiv/nsxiv/archive/v27.1.tar.gz)**
*(September 16, 2021)*
* Fixes:
* Source tarball failing build [#66]
[#66]: https://codeberg.org/nsxiv/nsxiv-record/pulls/66
- - -
**[v27](https://github.com/nsxiv/nsxiv/archive/v27.tar.gz)**
*(September 16, 2021)*
* Changes:
* Re-release under the name nsxiv.
* Xresources `Sxiv.foreground` and `Sxiv.background` changed
to `Nsxiv.window.foreground` and `Nsxiv.window.background`.
* Xresources `Sxiv.font` changed to `Nsxiv.bar.font`.
* Rework the build system. Now by default we'll build with only optional
dependencies that are already installed. [#19]
* Added:
* Fill scale mode. [#2]
* Configurable X window title (via `config.h` and the `-T` flag). [#23]
* Support custom bar colors via Xresources. [#19]
* Support custom mark color via Xresources. [#51]
* Toggle animation playback with <kbd>Ctrl-a</kbd>. [#33]
* Set `_NET_WM_PID` and `WM_CLIENT_MACHINE` X properties. [#13]
* Set `ICCCM WM manager` hints. [#12]
* Fixes:
* Cli flag `-G` not initially setting gamma. [#31]
* Wrong keybinding description in the manpage. [#14]
* .desktop entry not advertising webp support. [#15]
* Prevent crash when embedded into transparent window. [#3]
* Small memory leak. [#57]
* Rare crash when showing some GIFs. [#41]
* Rare event where nsxiv wouldn't close after window being destroyed. [#53]
[#2]: https://codeberg.org/nsxiv/nsxiv-record/pulls/2
[#3]: https://codeberg.org/nsxiv/nsxiv-record/pulls/3
[#12]: https://codeberg.org/nsxiv/nsxiv-record/pulls/12
[#13]: https://codeberg.org/nsxiv/nsxiv-record/pulls/13
[#14]: https://codeberg.org/nsxiv/nsxiv-record/pulls/14
[#15]: https://codeberg.org/nsxiv/nsxiv-record/pulls/15
[#19]: https://codeberg.org/nsxiv/nsxiv-record/pulls/19
[#23]: https://codeberg.org/nsxiv/nsxiv-record/pulls/23
[#31]: https://codeberg.org/nsxiv/nsxiv-record/pulls/31
[#33]: https://codeberg.org/nsxiv/nsxiv-record/pulls/33
[#41]: https://codeberg.org/nsxiv/nsxiv-record/pulls/41
[#51]: https://codeberg.org/nsxiv/nsxiv-record/pulls/51
[#53]: https://codeberg.org/nsxiv/nsxiv-record/pulls/53
[#57]: https://codeberg.org/nsxiv/nsxiv-record/pulls/57
sxiv
----
**Stable releases**
**[v26](https://github.com/nsxiv/nsxiv/archive/v26.tar.gz)**
*(January 16, 2020)*
* Maintenance release
**[v25](https://github.com/nsxiv/nsxiv/archive/v25.tar.gz)**
*(January 26, 2019)*
* Support font fallback for missing glyphs
* Fix busy loop when built without inotify
* Use background/foreground colors from X resource database
**[v24](https://github.com/nsxiv/nsxiv/archive/v24.tar.gz)**
*(October 27, 2017)*
* Automatically reload the current image whenever it changes
* Support embedding into other X windows with -e (e.g. tabbed)
* New option -p prevents sxiv from creating cache and temporary files
* Simpler mouse mappings, the most basic features are accessible with the
mouse only (navigate, zoom, pan)
**[v1.3.2](https://github.com/nsxiv/nsxiv/archive/v1.3.2.tar.gz)**
*(December 20, 2015)*
* external key handler gets file paths on stdin, not as arguments
* Cache out-of-view thumbnails in the background
* Apply gamma correction to thumbnails
**[v1.3.1](https://github.com/nsxiv/nsxiv/archive/v1.3.1.tar.gz)**
*(November 16, 2014)*
* Fixed build error, caused by delayed config.h creation
* Fixed segfault when run with -c
**[v1.3](https://github.com/nsxiv/nsxiv/archive/v1.3.tar.gz)**
*(October 24, 2014)*
* Extract thumbnails from EXIF tags (requires libexif)
* Zoomable thumbnails, supported sizes defined in config.h
* Fixed build error with giflib version >= 5.1.0
**[v1.2](https://github.com/nsxiv/nsxiv/archive/v1.2.tar.gz)**
*(April 24, 2014)*
* Added external key handler, called on keys prefixed with `Ctrl-x`
* New keybinding `{`/`}` to change gamma (by András Mohari)
* Support for slideshows, enabled with `-S` option & toggled with `s`
* Added application icon (created by 0ion9)
* Checkerboard background for alpha layer
* Option `-o` only prints files marked with `m` key
* Fixed rotation/flipping of multi-frame images (gifs)
**[v1.1.1](https://github.com/nsxiv/nsxiv/archive/v1.1.1.tar.gz)**
*(June 2, 2013)*
* Various bug fixes
**[v1.1](https://github.com/nsxiv/nsxiv/archive/v1.1.tar.gz)**
*(March 30, 2013)*
* Added status bar on bottom of window with customizable content
* New keyboard shortcuts `\`/`|`: flip image vertically/horizontally
* New keyboard shortcut `Ctrl-6`: go to last/alternate image
* Added own EXIF orientation handling, removed dependency on libexif
* Fixed various bugs
**[v1.0](https://github.com/nsxiv/nsxiv/archive/v1.0.tar.gz)**
*(October 31, 2011)*
* Support for multi-frame images & GIF animations
* POSIX compliant (IEEE Std 1003.1-2001)
**[v0.9](https://github.com/nsxiv/nsxiv/archive/v0.9.tar.gz)**
*(August 17, 2011)*
* Made key and mouse mappings fully configurable in config.h
* Complete code refactoring
**[v0.8.2](https://github.com/nsxiv/nsxiv/archive/v0.8.2.tar.gz)**
*(June 29, 2011)*
* POSIX-compliant Makefile; compiles under NetBSD
**[v0.8.1](https://github.com/nsxiv/nsxiv/archive/v0.8.1.tar.gz)**
*(May 8, 2011)*
* Fixed fullscreen under window managers, which are not fully EWMH-compliant
**[v0.8](https://github.com/nsxiv/nsxiv/archive/v0.8.tar.gz)**
*(April 18, 2011)*
* Support for thumbnail caching
* Ability to run external commands (e.g. jpegtran, convert) on current image
**[v0.7](https://github.com/nsxiv/nsxiv/archive/v0.7.tar.gz)**
*(February 26, 2011)*
* Sort directory entries when using `-r` command line option
* Hide cursor in image mode
* Full functional thumbnail mode, use Return key to switch between image and
thumbnail mode
**[v0.6](https://github.com/nsxiv/nsxiv/archive/v0.6.tar.gz)**
*(February 16, 2011)*
* Bug fix: Correctly display filenames with umlauts in window title
* Basic support of thumbnails
**[v0.5](https://github.com/nsxiv/nsxiv/archive/v0.5.tar.gz)**
*(February 6, 2011)*
* New command line option: `-r`: open all images in given directories
* New key shortcuts: `w`: resize image to fit into window; `W`: resize window
to fit to image
**[v0.4](https://github.com/nsxiv/nsxiv/archive/v0.4.tar.gz)**
*(February 1, 2011)*
* New command line option: `-F`, `-g`: use fixed window dimensions and apply
a given window geometry
* New key shortcut: `r`: reload current image
**[v0.3.1](https://github.com/nsxiv/nsxiv/archive/v0.3.1.tar.gz)**
*(January 30, 2011)*
* Bug fix: Do not set setuid bit on executable when using `make install`
* Pan image with mouse while pressing middle mouse button
**[v0.3](https://github.com/nsxiv/nsxiv/archive/v0.3.tar.gz)**
*(January 29, 2011)*
* New command line options: `-d`, `-f`, `-p`, `-s`, `-v`, `-w`, `-Z`, `-z`
* More mouse mappings: Go to next/previous image with left/right click,
scroll image with mouse wheel (horizontally if Shift key is pressed),
zoom image with mouse wheel if Ctrl key is pressed
**[v0.2](https://github.com/nsxiv/nsxiv/archive/v0.2.tar.gz)**
*(January 23, 2011)*
* Bug fix: Handle window resizes correctly
* New keyboard shortcuts: `g`/`G`: go to first/last image; `[`/`]`: go 10
images back/forward
* Support for mouse wheel zooming (by Dave Reisner)
* Added fullscreen mode
**[v0.1](https://github.com/nsxiv/nsxiv/archive/v0.1.tar.gz)**
*(January 21, 2011)*
* Initial release

View file

@ -1,112 +0,0 @@
Project Scope
-------------
* Bug fixes and maintenance
* Prioritize extensibility and simplicity
* Do not make the codebase more complex, keep it simple to hack on
* Do not add extra dependency (if we do, add compile time switch to disable it)
* New features may be added if it cannot be achieved (easily) via a shell script,
doesn't break backwards compatibility and doesn't violate any of the above rules.
Note: Since we aim to be a drop-in replacement for sxiv, we intend to keep all
sxiv's behaviors/features even in cases where removing them would make the
code-base simpler.
Also note that (n)sxiv uses `imlib2` for loading images. Thus any request or
patches for adding support for new image formats should go into
[imlib2's repo](https://git.enlightenment.org/old/legacy-imlib2) instead.
Contribution Guideline
----------------------
When contributing, make sure:
* Your contribution falls under nsxiv's scope and aim
* You follow the existing code style (see the "Code Style" section below)
* You open the pull request from a new branch, not from master
* To avoid using force pushes, especially for bigger patches. Only use them
when there's merge conflicts.
If your contribution is not suitable for general use, it will not be included in nsxiv.
For changes that are very much up to preference, such as changing values in config.h,
please do not open a pull request unless you have an objective explanation.
See the [open issues](https://codeberg.org/nsxiv/nsxiv/issues) to find something
to work on. You can also filter the issues via label:
* [Good first issue](https://codeberg.org/nsxiv/nsxiv/issues?labels=49698):
(Easy) Issues which do not require much if any experience.
* [Up for grabs](https://codeberg.org/nsxiv/nsxiv/issues?labels=49705):
(Intermediate) Issues which are free for anyone who wants to pick it up.
Might require some experience.
* [Help wanted](https://codeberg.org/nsxiv/nsxiv/issues?labels=49699):
(Intermediate/Experienced) Issues where we require some help.
Code Style
----------
`nsxiv` mostly follows the [suckless code-style][sl], with a few exceptions.
If your editor supports [.editorconfig](../.editorconfig) then you'll already be
off to a good start without needing much manual intervention. Additionally we
provide a [clang-format](./.clang-format) configuration for reference, which you
may use via [`git-clang-format`][cf] to format the changes you've made (please
do not run it globally on the entire code-base since clang-format gets a decent
amount of edge cases wrong).
[sl]: https://suckless.org/coding_style/
[cf]: https://clang.llvm.org/docs/ClangFormat.html#git-integration
Development workflow for maintainers
------------------------------------
If we notice you contributing and/or showing interest in issues/pull requests,
we may invite you to join the nsxiv org as a member. Being a member simply means
you will be able to approve, disapprove and merge pull requests.
Our workflow regarding pull requests is the following:
* Code related changes require two approvals, but documentation related
changes (e.g. typo) can be merged with just one.
* If a pull request has a single approval, no objections and has been open
for more than 7 days, then it may be force-merged.
* Always prefer squashing when merging. In the case a PR makes more than one
significant change, use the "don't squash" tag and rebase instead.
* When merging, make sure the commit message is cleaned up properly so that
it reflects the current intention of the PR.
For releases, the process is the following:
* Tag the release with a "vN" tag, where N is the version number. Also set
the commit message and tag description for the release commit to "Release
version N". Make sure to use an annotated tag.
* Update `VERSION` macro in `config.mk`.
* Update the changelog (`etc/CHANGELOG.md`):
* Include link to the release tarball and add the release date.
* Document only the changes or fixes between releases. Don't document
changes which never made it into a release.
* Use the "Changes" section to document behavior changes since the last
release, the "Added" section for new features, and the "Fixes" section
for fixed bugs or regressions.
* Include pull request IDs with reference style links.
Mirroring to GitHub:
Assuming `origin` is the name of the codeberg remote and `github` is the name
of the github remote; run the following commands to mirror the codeberg repo to
github:
```console
$ git fetch --prune origin
$ git push --prune github '+refs/remotes/origin/*:refs/heads/*' '+refs/tags/*:refs/tags/*'
```
The first command updates the local repo and the second command pushes
everything on `origin` without pushing any of the local branches.
- - -
For mundane development related talks which don't warrant their own issue, use
the [general discussion](https://codeberg.org/nsxiv/nsxiv/issues/294) thread.

View file

@ -1,53 +0,0 @@
# Migrating from `sxiv`
`nsxiv` is *mostly* a drop-in replacement for `sxiv`, but not fully.
This document outlines some key differences to be aware of if you're migrating
from `sxiv`.
### Configuration directory
`sxiv` looks for config files under the directory
`${XDG_CONFIG_HOME:-${HOME}/.config}/sxiv`. E.g
`~/.config/sxiv/exec/key-handler`.
`nsxiv` uses the same logic to find the config dir but uses the name "nsxiv".
E.g `~/.config/nsxiv/...`.
The "exec" scripts such as `key-handler` and `image-info` in `nsxiv` has some
more features, but all previous argument order are preserved. And so if you have
any exec scripts, you can simply copy them over and they should just work.
### Xresources
The xresources config for `nsxiv` is under the "Nsxiv" namespace whereas `sxiv`
uses the "Sxiv" namespace. Some of the variables are also different between
`nsxiv` and `sxiv`, below is a table that shows the old and new names:
| sxiv | nsxiv |
| :-- | :-- |
| Sxiv.background | Nsxiv.window.background |
| Sxiv.foreground | Nsxiv.window.foreground |
| Sxiv.barBackground | Nsxiv.bar.background |
| Sxiv.barForeground | Nsxiv.bar.foreground |
| Sxiv.font | Nsxiv.bar.font |
### Default window class
The window class of `nsxiv` is set to "Nsxiv" by default (can be overwritten via
`-N` flag). This usually shouldn't matter, unless you have scripts that search
for "Sxiv" window class.
### Thumbnail cache directory
Similar to config dir, the thumbnail cache dir of `nsxiv` is under the "nsxiv"
name instead of "sxiv". E.g `~/.cache/nsxiv`.
The "caching structure" in `nsxiv` is the same as `sxiv`. Which means that you
can simply rename the directory to `nsxiv`:
```console
$ mv ~/.cache/sxiv ~/.cache/nsxiv
```
If you want to have both `sxiv` and `nsxiv` installed at the same time, you can
even use symlink to avoid duplicate cache.

View file

@ -1,21 +0,0 @@
#!/bin/sh
# Example for $XDG_CONFIG_HOME/nsxiv/exec/image-info
# Called by nsxiv(1) whenever an image gets loaded.
# The output is displayed in nsxiv's status bar.
# Arguments:
# $1: path to image file (as provided by the user)
# $2: image width
# $3: image height
# $4: fully resolved path to the image file
s=" " # field separator
exec 2>/dev/null
filename=$(basename -- "$1")
filesize=$(du -Hh -- "$1" | cut -f 1)
geometry="${2}x${3}"
echo "${filesize}${s}${geometry}${s}${filename}"

View file

@ -1,41 +0,0 @@
#!/bin/sh
# Example for $XDG_CONFIG_HOME/nsxiv/exec/key-handler
# Called by nsxiv(1) after the external prefix key (C-x by default) is pressed.
# The next key combo is passed as its first argument. Passed via stdin are the
# images to act upon: all marked images, if in thumbnail mode and at least one
# image has been marked, otherwise the current image. nsxiv(1) will block until
# the handler terminates. It then checks which images have been modified and
# reloads them.
# By default nsxiv(1) will send one image per-line to stdin, however when using
# -0 the image list will be NULL separated and the environment variable
# "$NSXIV_USING_NULL" will be set to 1.
# The key combo argument has the following form: "[C-][M-][S-]KEY",
# where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X
# keysym as listed in /usr/include/X11/keysymdef.h without the "XK_" prefix.
# If KEY has an uppercase equivalent, S-KEY is resolved into it. For instance,
# K replaces S-k and Scedilla replaces S-scedilla, but S-Delete is sent as-is.
rotate() {
degree="$1"
tr '\n' '\0' | xargs -0 realpath | sort | uniq | while read file; do
case "$(file -b -i "$file")" in
image/jpeg*) jpegtran -rotate "$degree" -copy all -outfile "$file" "$file" ;;
*) mogrify -rotate "$degree" "$file" ;;
esac
done
}
case "$1" in
"C-x") xclip -in -filter | tr '\n' ' ' | xclip -in -selection clipboard ;;
"C-c") while read file; do xclip -selection clipboard -target image/png "$file"; done ;;
"C-e") while read file; do urxvt -bg "#444" -fg "#eee" -sl 0 -title "$file" -e sh -c "exiv2 pr -q -pa '$file' | less" & done ;;
"C-g") tr '\n' '\0' | xargs -0 gimp & ;;
"C-r") while read file; do rawtherapee "$file" & done ;;
"C-comma") rotate 270 ;;
"C-period") rotate 90 ;;
"C-slash") rotate 180 ;;
esac

View file

@ -1,20 +0,0 @@
#!/bin/sh
# Example for $XDG_CONFIG_HOME/nsxiv/exec/thumb-info
# Called by nsxiv(1) whenever the selected thumbnail changes.
# The output is displayed in nsxiv's status bar.
# Arguments:
# $1: path to image file (as provided by the user)
# $2: empty
# $3: empty
# $4: fully resolved path to the image file
s=" " # field separator
exec 2>/dev/null
filename=$(basename -- "$4")
filesize=$(du -Hh -- "$4" | cut -f 1)
echo "${filesize}${s}${filename}"

View file

@ -1,27 +0,0 @@
#!/bin/sh
# Example for $XDG_CONFIG_HOME/nsxiv/exec/win-title
# Called by nsxiv(1) whenever any of the relevant information changes.
# The output is set as nsxiv's window title.
#
# Arguments, "Optional" arguments might be empty:
# $1: resolved absolute path of the current file
# $2: current file number
# $3: total file number
# $4: image width (Optional: Disabled on thumbnails mode)
# $5: image height (Optional: Disabled on thumbnails mode)
# $6: current zoom (Optional: Disabled on thumbnails mode)
#
# The term file is used rather than image as nsxiv does not
# precheck that the input files are valid images. Total file
# count may be different from the actual count of valid images.
exec 2>/dev/null
filename="${1##*/}"
if [ -n "$4" ]; then # image mode
printf "%s" "nsxiv - ${filename} | ${4}x${5} ${6}% [${2}/${3}]"
else
printf "%s" "nsxiv - ${filename} [${2}/${3}]"
fi

View file

@ -1,618 +0,0 @@
.TH NSXIV 1 nsxiv\-VERSION
.SH NAME
nsxiv \- Neo Simple X Image Viewer
.SH SYNOPSIS
.B nsxiv
.RB [ \-abcfhiopqrtvZ0 ]
.RB [ \-A
.IR FRAMERATE ]
.RB [ \-e
.IR WID ]
.RB [ \-G
.IR GAMMA ]
.RB [ \-g
.IR GEOMETRY ]
.RB [ \-N
.IR NAME ]
.RB [ \-n
.IR NUM ]
.RB [ \-S
.IR DELAY ]
.RB [ \-s
.IR MODE ]
.RB [ \-z
.IR ZOOM ]
.IR FILE ...
.SH DESCRIPTION
nsxiv is a simple image viewer for X.
.P
It has two modes of operation: image and thumbnail mode. The default is image
mode, in which only the current image is shown. In thumbnail mode a grid of
small previews is displayed, making it easy to choose an image to open.
.P
Please note, that the fullscreen mode requires an EWMH/NetWM-compliant window
manager.
.SH OPTIONS
.TP
.BI "\-A, \-\-framerate " FRAMERATE
Play animations with a constant frame rate set to
.IR FRAMERATE .
.TP
.B "\-a, \-\-animate"
Play animations of multi-frame images.
.TP
.B "\-b, \-\-no\-bar"
Do not show statusbar at the bottom of the window.
.TP
.B "\-c, \-\-clean\-cache"
Remove all orphaned cache files from the thumbnail cache directory and exit.
.TP
.BI "\-e, \-\-embed " WID
Embed nsxiv's window into window whose ID is
.IR WID .
.TP
.B "\-f, \-\-fullscreen"
Start in fullscreen mode.
.TP
.BI "\-G, \-\-gamma " GAMMA
Set image gamma to GAMMA (\-32..32).
.TP
.BI "\-g, \-\-geometry " GEOMETRY
Set window position and size. See section GEOMETRY SPECIFICATIONS of X(7) for
more information on GEOMETRY argument.
.TP
.B "\-h, \-\-help"
Print brief usage information to standard output and exit.
.TP
.B "\-i, \-\-stdin"
Read names of files to open from standard input. Also done if FILE is `-'.
.TP
.BI "\-N, \-\-class " NAME
Set the resource name (WM_CLASS) of nsxiv's X window to NAME.
.TP
.BI "\-n, \-\-start\-at " NUM
Start at picture number NUM.
.TP
.B "\-o, \-\-stdout"
Write list of all marked files to standard output when quitting. In combination
with
.B "\-i, \-\-stdin"
nsxiv can be used as a visual filter/pipe.
.TP
.B "\-p, \-\-private"
Enable private mode, in which nsxiv does not write any cache or temporary files.
.TP
.B "\-q, \-\-quiet"
Be quiet, and disable warnings to standard error stream.
.TP
.B "\-r, \-\-recursive"
Search the given directories recursively for images to view.
.TP
.BI "\-S, \-\-ss\-delay " DELAY
Start in slideshow mode. Set the delay between images to
.I DELAY
seconds.
.I DELAY
may be a floating-point number.
.TP
.BI "\-s, \-\-scale\-mode " MODE
Set scale mode according to MODE character. Supported modes are: [d]own,
[f]it, [F]ill, [w]idth, [h]eight.
.TP
.B "\-t, \-\-thumbnail"
Start in thumbnail mode.
.TP
.B "\-v, \-\-version"
Print version information to standard output and exit.
.TP
.B "\-Z, \-\-zoom\-100"
The same as `\-z 100'.
.TP
.BI "\-z, \-\-zoom " ZOOM
Set zoom level to ZOOM percent.
.TP
.B "\-0, \-\-null"
Use NULL-separator. With this option, output of \-o and file-list sent to the
key-handler and the input of \-i will be separated by a NULL character.
.TP
.BI "\-\-anti\-alias" [=no]
Enables anti-aliasing, when given
.I no
as an argument, disables it instead.
.TP
.BI "\-\-alpha\-layer" [=no]
Enables checkerboard background for alpha layer, when given
.I no
as an argument, disables it instead.
.TP
.BI "\-\-cache\-allow, \-\-cache\-deny " "CACHE\-PATHS"
List of directories to whitelist or blacklist for thumbnail caching.
See
.I "THUMBNAIL CACHING"
section for more information on the argument format.
These options are mutually exclusive, if they are specified more than once then
only the final one takes effect.
.SH KEYBOARD COMMANDS
.SS General
The following keyboard commands are available in both image and thumbnail modes:
.TP
.BR 0 \- 9
Prefix the next command with a number (denoted via
.IR count ).
.TP
.B q
Quit nsxiv.
.TP
.B Q
Quit nsxiv, but additionally print the current filename when \-o is active and
no files have been marked.
.TP
.B Return
Switch to thumbnail mode / open selected image in image mode.
.TP
.B f
Toggle fullscreen mode.
.TP
.B b
Toggle visibility of statusbar at the bottom of the window.
.TP
.B Ctrl-x
Send the next key to the external key-handler. See section EXTERNAL KEY HANDLER
for more information.
.TP
.B g
Go to the first image.
.TP
.B G
Go to the last image, or image number
.IR count .
.TP
.B r
Reload image.
.TP
.B D
Remove current image from file list and go to next image.
.TP
.BR Ctrl-h ", " Ctrl-Left
Scroll left one screen width.
.TP
.BR Ctrl-j ", " Ctrl-Down
Scroll down one screen height.
.TP
.BR Ctrl-k ", " Ctrl-Up
Scroll up one screen height.
.TP
.BR Ctrl-l ", " Ctrl-Right
Scroll right one screen width.
.TP
.BR +
Zoom in.
.TP
.B \-
Zoom out.
.TP
.B m
Mark/unmark the current image.
.TP
.B M
Mark/unmark all images starting from the last marked/unmarked image up to the
current one.
.TP
.B Ctrl-m
Reverse all image marks.
.TP
.B Ctrl-u
Remove all image marks.
.TP
.B N
Go
.I count
marked images forward.
.TP
.B P
Go
.I count
marked images backward.
.TP
.B {
Decrease gamma correction by
.I count
steps.
.TP
.B }
Increase gamma correction by
.I count
steps.
.TP
.B Ctrl-g
Reset gamma correction.
.TP
.B Ctrl-[
Decrease brightness correction by
.I count
steps.
.TP
.B Ctrl-]
Increase brightness correction by
.I count
steps.
.TP
.B (
Decrease contrast by
.I count
steps.
.TP
.B )
Increase contrast by
.I count
steps.
.SS Thumbnail mode
The following keyboard commands are only available in thumbnail mode:
.TP
.BR h ", " Left
Move selection left
.I count
times.
.TP
.BR j ", " Down
Move selection down
.I count
times.
.TP
.BR k ", " Up
Move selection up
.I count
times.
.TP
.BR l ", " Right
Move selection right
.I count
times.
.TP
.B R
Reload all thumbnails.
.SS Image mode
The following keyboard commands are only available in image mode:
.TP
Navigate image list:
.TP
.BR n ", " Space
Go
.I count
images forward.
.TP
.BR p ", " Backspace
Go
.I count
images backward.
.TP
.B [
Go
.I count
* 10 images backward.
.TP
.B ]
Go
.I count
* 10 images forward.
.TP
.B Ctrl-6
Go to the previously viewed image.
.TP
Handle multi-frame images:
.TP
.B Ctrl-n
Go
.I count
frames of a multi-frame image forward.
.TP
.B Ctrl-p
Go
.I count
frames of a multi-frame image backward.
.TP
.BR Ctrl-a ", " Ctrl-Space
Play/stop animations of multi-frame images.
.TP
Panning:
.TP
.BR h ", " Left
Scroll image 1/5 of window width or
.I count
pixels left.
.TP
.BR j ", " Down
Scroll image 1/5 of window height or
.I count
pixels down.
.TP
.BR k ", " Up
Scroll image 1/5 of window height or
.I count
pixels up.
.TP
.BR l ", " Right
Scroll image 1/5 of window width or
.I count
pixels right.
.TP
.B H
Scroll to left image edge.
.TP
.B J
Scroll to bottom image edge.
.TP
.B K
Scroll to top image edge.
.TP
.B L
Scroll to right image edge.
.TP
.B z
Scroll to image center.
.TP
Zooming:
.TP
.B =
Set zoom level to 100%, or
.IR count %.
.TP
.B w
Set zoom level to 100%, but fit large images into window.
.TP
.B W
Fit image to window.
.TP
.B F
Fill image to window.
.TP
.B e
Fit image to window width.
.TP
.B E
Fit image to window height.
.TP
Rotation:
.TP
.B <
Rotate image counter-clockwise by 90 degrees.
.TP
.B >
Rotate image clockwise by 90 degrees.
.TP
.B ?
Rotate image by 180 degrees.
.TP
Flipping:
.TP
.B |
Flip image horizontally.
.TP
.B _
Flip image vertically.
.TP
Miscellaneous:
.TP
.B a
Toggle anti-aliasing.
.TP
.B A
Toggle visibility of alpha-channel, i.e. image transparency.
.TP
.B s
Toggle slideshow mode and/or set the delay between images to
.I count
seconds.
.SH MOUSE COMMANDS
.SS Thumbnail mode
The following mouse mappings are available in thumbnail mode:
.TP
.B Button1
Select the image. Goes into image mode if double\-clicked.
.TP
.B Button3
Mark/unmark the image. Dragging while holding down Button3 will mark/unmark
multiple images.
.TP
.B Button4
Scroll up by one row.
.TP
.B Button5
Scroll down by one row.
.TP
.B Ctrl-Button4
Scroll up by one page.
.TP
.B Ctrl-Button5
Scroll down by one page.
.SS Image mode
The following mouse mappings are available in image mode:
.TP
.B Button1
Go to the next image if the mouse cursor is in the right part of the window or
to the previous image if it is in the left part.
.TP
.B Ctrl-Button1
Pan the image relative to the mouse cursor.
.TP
.B Button2
Pan the image according to the mouse cursor position in the window while
keeping this button pressed down.
.TP
.B Button3
Switch to thumbnail mode.
.TP
.B Button4
Zoom in.
.TP
.B Button5
Zoom out.
.SH CONFIGURATION
The following X resources are supported under "Nsxiv" (e.g.
.B Nsxiv.bar.font
):
.TP
.B window.background
Color of the window background
.TP
.B window.foreground
Color of the window foreground
.TP
.B bar.font
Name of Xft bar font
.TP
.B bar.background
Color of the bar background. Defaults to window.background
.TP
.B bar.foreground
Color of the bar foreground. Defaults to window.foreground
.TP
.B mark.foreground
Color of the mark foreground. Defaults to window.foreground
.TP
Please see xrdb(1) on how to change them.
.LP
An X resources entry with an empty value means the default
(defined in config.h) will be used.
.SH WINDOW TITLE
The window title can be replaced with the output of a user-provided script,
which is called by nsxiv whenever any of the relevant information changes.
The path of this script is
.I $XDG_CONFIG_HOME/nsxiv/exec/win-title
and the arguments given to it (where "Optional" arguments might be empty) are:
.IP $1 4
resolved absolute path of the current file
.IP $2 4
current file number
.IP $3 4
total file count
.IP $4 4
image width (Optional: Disabled on thumbnails mode)
.IP $5 4
image height (Optional: Disabled on thumbnails mode)
.IP $6 4
current zoom (Optional: Disabled on thumbnails mode)
.P
The term file is used rather than image as nsxiv does not precheck that the
input files are valid images. Total file count may be different from the actual
count of valid images.
.P
There is also an example script installed together with nsxiv as
.IR EGPREFIX/win-title .
.SH STATUS BAR
The information displayed on the left side of the status bar can be replaced
with the output of user-provided script.
.P
The script that is called by nsxiv whenever an image gets loaded is located at
.I $XDG_CONFIG_HOME/nsxiv/exec/image-info
and the arguments given to it are:
.IP $1 4
path to image file (as provided by the user)
.IP $2 4
image width
.IP $3 4
image height
.IP $4 4
fully resolved path to the image file
.P
In thumbnail mode, the script that is called is located at
.I $XDG_CONFIG_HOME/nsxiv/exec/thumb-info
and the arguments given to it are:
.IP $1 4
path to image file (as provided by the user)
.IP $2 4
empty
.IP $3 4
empty
.IP $4 4
fully resolved path to the image file
.P
There are also example scripts installed together with nsxiv as
.IR EGPREFIX/image-info
and
.IR EGPREFIX/thumb-info .
.SH EXTERNAL KEY HANDLER
Additional external keyboard commands can be defined using a handler program
located in
.IR $XDG_CONFIG_HOME/nsxiv/exec/key-handler .
The handler is invoked by pressing
.BR Ctrl-x .
The next key combo is passed as its first argument. Passed via stdin are the
images to act upon: all marked images, if in thumbnail mode and at least one
image has been marked, otherwise the current image. nsxiv(1) will block until
the handler terminates. It then checks which images have been modified and
reloads them.
By default nsxiv(1) will send one image per-line to stdin, however when using
\-0 the image list will be NULL separated and the environment variable
"$NSXIV_USING_NULL" will be set to 1.
The key combo argument has the following form: "[C-][M-][S-]KEY",
where C/M/S indicate Ctrl/Meta(Alt)/Shift modifier states and KEY is the X
keysym as listed in /usr/include/X11/keysymdef.h without the "XK_" prefix.
If KEY has an uppercase equivalent, S-KEY is resolved into it. For instance,
K replaces S-k and Scedilla replaces S-scedilla, but S-Delete is sent as-is.
There is also an example script installed together with nsxiv as
.IR EGPREFIX/key-handler .
.SH THUMBNAIL CACHING
nsxiv stores all thumbnails under
.IR $XDG_CACHE_HOME/nsxiv/ .
.P
Use the command line option
.I \-c
to remove all orphaned cache files. Additionally, run the following command
afterwards inside the cache directory to remove empty subdirectories:
.P
.RS
find . \-depth \-type d \-empty ! \-name '.' \-exec rmdir {} \\;
.RE
.P
The option
.BR "\-\-cache\-allow " or " \-\-cache\-deny"
may be used to whitelists or blacklist certain directories from being cached.
The argument is a
.B :
separated list of paths. A
.B *
at the beginning of the path indicates that path should be matched recursively.
.P
For example:
.B \-\-cache\-allow \(dq/user/pictures:*/media/pictures\(dq
whitelists \(dq/user/pictures\(dq directory non-recursively and \(dq/media/pictures\(dq
directory recursively. Nothing outside these two directories will be cached.
And
.B \-\-cache\-deny \(dq*/secret\(dq
will enable blacklist mode and will not cache anything inside \(dq/secret\(dq
or it's subdirectories.
.SH ORIGINAL AUTHOR
.EX
Bert Muennich <ber.t at posteo.de>
.EE
.SH CURRENT MAINTAINERS
.EX
NRK <nrk at disroot.org>
Berke Kocaoğlu <berke.kocaoglu at metu.edu.tr>
TAAPArthur <taaparthur at gmail.com>
eylles <ed.ylles1997 at gmail.com>
Stein Gunnar Bakkeby <bakkeby at gmail.com>
explosion-mental <explosion0mental at gmail.com>
.EE
.SH CONTRIBUTORS
.EX
For a list of contributors, run `git shortlog -s` in the nsxiv git repository.
.EE
.SH HOMEPAGE
.TP
Website:
.EE
https://nsxiv.codeberg.page/
.EX
.TP
Source code:
.EE
https://codeberg.org/nsxiv/nsxiv
.EX
.SH SEE ALSO
.BR X (7),
.BR xrdb (1)

View file

@ -1,8 +0,0 @@
[Desktop Entry]
Type=Application
Name=nsxiv
GenericName=Image Viewer
Exec=nsxiv %F
MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/png;image/tiff;image/x-bmp;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-tga;image/x-xpixmap;image/webp;image/heic;image/svg+xml;application/postscript;image/jp2;image/jxl;image/avif;image/heif;
NoDisplay=true
Icon=nsxiv

View file

@ -1,13 +0,0 @@
# vanilla flags
-std=c99 -Wall -pedantic
# optimizations: enables extra warnings and deeper analysis thus catches more errors/warnings
-O3 -flto
# treat warnings as errors
-Werror
# extra flags
-Wextra -Wshadow -Wvla -Wpointer-arith
-Wundef -Wstrict-overflow=4 -Wwrite-strings -Wunreachable-code
-Wbad-function-cast -Wdeclaration-after-statement
-Wmissing-prototypes -Wstrict-prototypes
# silence
-Wno-unused-parameter -Wno-missing-field-initializers

View file

@ -1,24 +0,0 @@
#!/bin/sh -e
std="c99"
NProc=$(( $(nproc) / 4 ))
if [ -z "$NProc" ] || [ "$NProc" -lt 1 ]; then NProc="1"; fi
run_cppcheck() {
cppcheck --std="$std" --enable=performance,portability \
--force --quiet --inline-suppr --error-exitcode=1 \
--max-ctu-depth=8 -j"$NProc" \
$(make OPT_DEP_DEFAULT="$1" dump_cppflags) -DDEBUG \
--suppress=varFuncNullUB --suppress=uninitvar \
$(git ls-files *.c)
}
run_tidy() {
checks="$(sed '/^#/d' etc/woodpecker/clang-tidy-checks | paste -d ',' -s)"
git ls-files *.c | xargs -P"$NProc" -I{} clang-tidy --quiet \
--warnings-as-errors="*" --checks="$checks" {} \
-- -std="$std" $(make OPT_DEP_DEFAULT="$1" dump_cppflags) -DDEBUG
}
run_cppcheck "0" & run_cppcheck "1" & run_tidy "0" & run_tidy "1";
wait

View file

@ -1,12 +0,0 @@
when:
branch: master
steps:
analysis:
image: alpine
commands: |
apk add --no-cache build-base cppcheck clang-extra-tools git \
imlib2-dev xorgproto \
libxft-dev libexif-dev >/dev/null
make config.h version.h
./etc/woodpecker/analysis.sh

View file

@ -1,31 +0,0 @@
when:
branch: master
# NOTE: "stable" tcc is too old and fails at linking. instead fetching a recent known working commit.
steps:
build:
image: alpine
environment:
- TCC_SHA=29ae3ed4d5b83eec43598d6cd7949bccb41c8083
commands: |
apk add --no-cache \
imlib2 imlib2-dev xorgproto \
libxft libxft-dev libexif libexif-dev \
gcc clang llvm llvm-dev build-base wget ca-certificates bc >/dev/null
wget "https://github.com/TinyCC/tinycc/archive/$TCC_SHA.tar.gz" >/dev/null
tar xzf "$TCC_SHA.tar.gz" >/dev/null
( cd "tinycc-$TCC_SHA" && ./configure --config-musl && make -s -j"$(nproc)" && make install; ) >/dev/null
CFLAGS="$(sed '/^#/d' etc/woodpecker/CFLAGS | paste -d ' ' -s)"
build () {
for cc in "gcc" "clang"; do
echo "### $cc - $2 build ###"
make clean && make -s -j"$(nproc)" CC="$cc" CFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" OPT_DEP_DEFAULT="$1"
done
}
# try all combination with tcc #
etc/woodpecker/try-all-builds.sh
# full-build with gcc and clang #
build "1" "full"
# ensure minimal-build works without opt deps installed
apk del libxft libxft-dev libexif libexif-dev >/dev/null
build "0" "minimal"

View file

@ -1,16 +0,0 @@
# checks
clang-analyzer-*,clang-diagnostic-*,bugprone-*,performance-*,modernize-*
misc-*,android-cloexec-*,llvm-include-order
-readability-*,readability-duplicate-include,readability-misleading-indentation
# silence
-misc-unused-parameters,-misc-include-cleaner,-misc-no-recursion
-bugprone-easily-swappable-parameters,-bugprone-narrowing-conversions,-bugprone-incorrect-roundings
-bugprone-implicit-widening-of-multiplication-result,-bugprone-integer-division
-android-cloexec-fopen,-android-cloexec-pipe,-cert-err33-c
-bugprone-assignment-in-if-condition
-bugprone-suspicious-realloc-usage
-bugprone-switch-missing-default-case
# false positive warnings
-clang-analyzer-valist.Uninitialized

View file

@ -1,13 +0,0 @@
when:
branch: master
# NOTE: codespell not available on stable alpine, grab it from pip
steps:
spell-check:
image: alpine:edge
commands: |
apk add --no-cache python3 py3-pip git
python3 -m venv ~/py3-venv
. ~/py3-venv/bin/activate
pip install codespell
git ls-files | sed '/\.png$/d' | xargs codespell

View file

@ -1,38 +0,0 @@
#!/bin/sh
#
# Shell script that checks for all possible build combination with TCC.
# Usage: call the script while in the nsxiv root directory
set -- $(grep -o '^HAVE_[[:alpha:]]* ' config.mk)
CFLAGS="$(sed '/^#/d' etc/woodpecker/CFLAGS | paste -d ' ' -s)"
z=$(echo "2 ^ $#" | bc)
print_opt_name() {
shift "$(( $1 + 1 ))"
printf "%s=" "$1"
}
print_opt_arg() {
bn=$(echo "$1 / (2 ^ $2)" | bc)
printf "%d " $(( bn % 2 ))
}
n=0
while [ "$n" -lt "$z" ]; do
i=0
while [ "$i" -lt "$#" ]; do
print_opt_name "$i" "$@"
print_opt_arg "$n" "$i"
i=$((i + 1))
done | tee "/dev/stderr" | (
make clean
if ! xargs make -j"$(nproc)" CC=tcc CFLAGS="$CFLAGS" LDFLAGS="$CFLAGS"; then
echo "[FAILED]" >&2
exit 1
else
echo "[SUCCESS]" >&2
fi
)
[ "$?" -ne 0 ] && exit "$?"
n=$((n + 1))
done >/dev/null

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

View file

@ -1,43 +0,0 @@
img2data
--------
img2data is a helper program to convert images to binary data for embedding in
software. The generated data is used in nsxiv to set the window icons.
How It Works
------------
Each given image is compressed using run-length encoding and a data array is
generated. In these arrays, the four high bits of each byte are the run length
minus one and the lowest four bits are the data, which are indices for the
color array.
See `data.gen.h` or the output of img2data for a better understanding.
Dependencies
------------
img2data requires Imlib2 to be installed.
Building
--------
img2data is built using the command:
$ CC -Wall -std=c89 -pedantic -lImlib2 img2data.c -o img2data
where `CC` is a C compiler such as `gcc`.
Usage
-----
img2data is used as the following:
$ ./img2data 16x16.png 32x32.png 48x48.png 64x64.png 128x128.png
You may replace or omit any image, but you must have a `data.gen.h` with at
least 1 image for nsxiv to compile.

View file

@ -1,157 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <Imlib2.h>
/* macros */
#define ARRLEN(a) (sizeof(a) / sizeof((a)[0]))
/* globals */
static unsigned long palette[16] = {0};
static unsigned int palette_size = 0;
static unsigned int run_column = 0;
static unsigned int icon_sizes[16] = {0};
static unsigned int icon_sizes_size = 0;
/* functions */
static void error(int eval, int err, const char *fmt, ...)
{
va_list ap;
fflush(stdout);
va_start(ap, fmt);
if (fmt)
vfprintf(stderr, fmt, ap);
va_end(ap);
if (err)
fprintf(stderr, "%s%s", fmt ? ": " : "", strerror(err));
fputc('\n', stderr);
if (eval)
exit(eval);
}
static unsigned long color_to_ulong(Imlib_Color color)
{
return (color.alpha << 24 & 0xff000000) |
(color.red << 16 & 0x00ff0000) |
(color.green << 8 & 0x0000ff00) |
(color.blue & 0x000000ff);
}
static int to_palette(unsigned long color)
{
unsigned int i;
for (i = 0; i < palette_size; i++) {
if (palette[i] == color)
return i;
}
if (palette_size + 1 == 16)
error(EXIT_FAILURE, 0, "Error: More than 16 colors in palette");
palette[palette_size] = color;
return palette_size++;
}
static void print_run(int color, unsigned int run_length)
{
while (run_length > 0) {
int x = run_length / 16 >= 1 ? 16 : run_length;
printf("0x%02x, ", (x - 1) << 4 | color);
run_length -= x;
if (++run_column % 12 == 0)
printf("\n\t");
}
}
static void print_palette(void)
{
unsigned int i;
printf("static const unsigned long icon_colors[] = {\n\t");
for (i = 0; i < palette_size; i++) {
printf("0x%08lx, ", palette[i]);
if (i % 4 == 3)
printf("\n\t");
}
printf("\n};\n\n");
}
static void print_icon_array(void)
{
unsigned int i;
printf("static const icon_data_t icons[] = {\n");
for (i = 0; i < icon_sizes_size; i++)
printf("\tICON_(%d),\n", icon_sizes[i]);
printf("};\n\n");
}
static unsigned int print_encoded_image(const char *path)
{
Imlib_Image image;
Imlib_Color color;
unsigned int width, height, x, y;
unsigned int run_length = 1;
int currentcolor = 0;
int lastcolor = -1;
image = imlib_load_image(path);
if (image == NULL)
error(EXIT_FAILURE, 0, "Error loading image: %s", path);
imlib_context_set_image(image);
width = imlib_image_get_width();
height = imlib_image_get_height();
if (width != height)
error(EXIT_FAILURE, 0, "Image is not square: %s", path);
printf("static const unsigned char icon_data_%d[] = {\n\t", width);
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
imlib_image_query_pixel(x, y, &color);
currentcolor = to_palette(color_to_ulong(color));
if (currentcolor != lastcolor) {
if (lastcolor != -1)
print_run(lastcolor, run_length);
run_length = 1;
} else {
run_length++;
}
lastcolor = currentcolor;
}
}
print_run(lastcolor, run_length);
printf("\n};\n\n");
imlib_free_image();
return width;
}
int main(int argc, char **argv)
{
unsigned int img_size = 0;
unsigned int i;
if (argc < 2)
error(EXIT_FAILURE, 0, "No icons provided");
else if (argc-1 > ARRLEN(icon_sizes))
error(EXIT_FAILURE, 0, "Too many icons");
for (i = 1; i < argc; i++) {
img_size = print_encoded_image(argv[i]);
run_column = 0;
icon_sizes[icon_sizes_size++] = img_size;
}
print_palette();
print_icon_array();
return EXIT_SUCCESS;
}

2
main.c
View file

@ -912,7 +912,7 @@ int main(int argc, char *argv[])
} }
if (options->filecnt == 0 && !options->from_stdin) { if (options->filecnt == 0 && !options->from_stdin) {
print_usage(); print_usage(stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View file

@ -26,6 +26,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h>
#include <Imlib2.h> #include <Imlib2.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -281,7 +282,7 @@ struct opt {
extern const opt_t *options; extern const opt_t *options;
void print_usage(void); void print_usage(FILE *stream);
void parse_options(int, char**); void parse_options(int, char**);

View file

@ -39,9 +39,10 @@
const opt_t *options; const opt_t *options;
void print_usage(void) void print_usage(FILE *stream)
{ {
printf("usage: %s [-abcfhiopqrtvZ0] [-A FRAMERATE] [-e WID] [-G GAMMA] " fprintf(stream,
"usage: %s [-abcfhiopqrtvZ0] [-A FRAMERATE] [-e WID] [-G GAMMA] "
"[-g GEOMETRY] [-N NAME] [-n NUM] [-S DELAY] [-s MODE] " "[-g GEOMETRY] [-N NAME] [-n NUM] [-S DELAY] [-s MODE] "
"[-z ZOOM] FILES...\n", "[-z ZOOM] FILES...\n",
progname); progname);
@ -66,6 +67,13 @@ static void print_version(void)
"\n", stdout); "\n", stdout);
} }
static bool parse_optional_no(const char *flag, const char *arg)
{
if (arg != NULL && !STREQ(arg, "no"))
error(EXIT_FAILURE, 0, "Invalid argument for option --%s: %s", flag, arg);
return arg == NULL;
}
void parse_options(int argc, char **argv) void parse_options(int argc, char **argv)
{ {
enum { enum {
@ -75,6 +83,8 @@ void parse_options(int argc, char **argv)
OPT_START = UCHAR_MAX, OPT_START = UCHAR_MAX,
OPT_AA, OPT_AA,
OPT_AL, OPT_AL,
OPT_THUMB,
OPT_BAR,
OPT_BG, OPT_BG,
OPT_CA, OPT_CA,
OPT_CD OPT_CD
@ -83,6 +93,7 @@ void parse_options(int argc, char **argv)
{ "framerate", 'A', OPTPARSE_REQUIRED }, { "framerate", 'A', OPTPARSE_REQUIRED },
{ "animate", 'a', OPTPARSE_NONE }, { "animate", 'a', OPTPARSE_NONE },
{ "no-bar", 'b', OPTPARSE_NONE }, { "no-bar", 'b', OPTPARSE_NONE },
{ "bar", OPT_BAR, OPTPARSE_NONE },
{ "clean-cache", 'c', OPTPARSE_NONE }, { "clean-cache", 'c', OPTPARSE_NONE },
{ "embed", 'e', OPTPARSE_REQUIRED }, { "embed", 'e', OPTPARSE_REQUIRED },
{ "fullscreen", 'f', OPTPARSE_NONE }, { "fullscreen", 'f', OPTPARSE_NONE },
@ -98,7 +109,9 @@ void parse_options(int argc, char **argv)
{ "recursive", 'r', OPTPARSE_NONE }, { "recursive", 'r', OPTPARSE_NONE },
{ "ss-delay", 'S', OPTPARSE_REQUIRED }, { "ss-delay", 'S', OPTPARSE_REQUIRED },
{ "scale-mode", 's', OPTPARSE_REQUIRED }, { "scale-mode", 's', OPTPARSE_REQUIRED },
{ "thumbnail", 't', OPTPARSE_NONE }, /* short opt `-t` doesn't accept optional arg for backwards compatibility reasons */
{ NULL, 't', OPTPARSE_NONE },
{ "thumbnail", OPT_THUMB, OPTPARSE_OPTIONAL },
{ "version", 'v', OPTPARSE_NONE }, { "version", 'v', OPTPARSE_NONE },
{ "zoom-100", 'Z', OPTPARSE_NONE }, { "zoom-100", 'Z', OPTPARSE_NONE },
{ "zoom", 'z', OPTPARSE_REQUIRED }, { "zoom", 'z', OPTPARSE_REQUIRED },
@ -163,19 +176,20 @@ void parse_options(int argc, char **argv)
switch (opt) { switch (opt) {
case '?': case '?':
fprintf(stderr, "%s\n", op.errmsg); fprintf(stderr, "%s\n", op.errmsg);
print_usage(); print_usage(stderr);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
case 'A': case 'A':
n = strtol(op.optarg, &end, 0); n = strtol(op.optarg, &end, 0);
if (*end != '\0' || n <= 0 || n > INT_MAX) if (*end != '\0' || n < 0 || n > INT_MAX)
error(EXIT_FAILURE, 0, "Invalid framerate: %s", op.optarg); error(EXIT_FAILURE, 0, "Invalid framerate: %s", op.optarg);
_options.framerate = n; _options.framerate = n;
/* fall through */ _options.animate = n > 0;
break;
case 'a': case 'a':
_options.animate = true; _options.animate = true;
break; break;
case 'b': case 'b': case OPT_BAR:
_options.hide_bar = true; _options.hide_bar = (opt == 'b');
break; break;
case 'c': case 'c':
_options.clean_cache = true; _options.clean_cache = true;
@ -199,7 +213,7 @@ void parse_options(int argc, char **argv)
_options.geometry = op.optarg; _options.geometry = op.optarg;
break; break;
case 'h': case 'h':
print_usage(); print_usage(stdout);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'i': case 'i':
_options.from_stdin = true; _options.from_stdin = true;
@ -258,19 +272,16 @@ void parse_options(int argc, char **argv)
_options.using_null = true; _options.using_null = true;
break; break;
case OPT_AA: case OPT_AA:
if (op.optarg != NULL && !STREQ(op.optarg, "no")) _options.anti_alias = parse_optional_no("anti-alias", op.optarg);
error(EXIT_FAILURE, 0, "Invalid argument for option --anti-alias: %s", op.optarg);
_options.anti_alias = op.optarg == NULL;
break; break;
case OPT_AL: case OPT_AL:
if (op.optarg != NULL && !STREQ(op.optarg, "no")) _options.alpha_layer = parse_optional_no("alpha-layer", op.optarg);
error(EXIT_FAILURE, 0, "Invalid argument for option --alpha-layer: %s", op.optarg); break;
_options.alpha_layer = op.optarg == NULL; case OPT_THUMB:
_options.thumb_mode = parse_optional_no("thumbnail", op.optarg);
break; break;
case OPT_BG: case OPT_BG:
if (op.optarg != NULL && !STREQ(op.optarg, "no")) _options.background_cache = parse_optional_no("bg-cache", op.optarg);
error(EXIT_FAILURE, 0, "Invalid argument for option --bg-cache: %s", op.optarg);
_options.background_cache = op.optarg == NULL;
break; break;
case OPT_CA: case OPT_CD: case OPT_CA: case OPT_CD:
_options.tns_filters = op.optarg; _options.tns_filters = op.optarg;

17
shell.nix Normal file
View file

@ -0,0 +1,17 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
gnumake
gcc
pkg-config
xorg.libX11
xorg.libXft
xorg.libXinerama
xorg.libXext
fontconfig
freetype
imlib2
libexif
];
}

View file

@ -67,6 +67,11 @@ static struct {
#if HAVE_LIBFONTS #if HAVE_LIBFONTS
static XftFont *font; static XftFont *font;
static double fontsize; static double fontsize;
/* utf8 ellipsis "…". the buffer must be at least 4 bytes for utf8_decode() */
enum { ELLIPSIS_LEN = 3 };
static const unsigned char ellipsis[4] = { 0xe2, 0x80, 0xa6, 0x0 };
static int ellipsis_w;
static int win_draw_text(win_t *, XftDraw *, const XftColor *, int, int, char *, int, int);
#endif #endif
#if HAVE_LIBFONTS #if HAVE_LIBFONTS
@ -96,17 +101,19 @@ static void win_alloc_color(const win_env_t *e, const char *name, XColor *col)
static const char *win_res(XrmDatabase db, const char *name, const char *def) static const char *win_res(XrmDatabase db, const char *name, const char *def)
{ {
char *type;
XrmValue ret;
if (db != NULL &&
XrmGetResource(db, name, name, &type, &ret) &&
STREQ(type, "String") && *ret.addr != '\0')
{
return ret.addr;
} else {
return def; return def;
}
// char *type;
// XrmValue ret;
//
// if (db != NULL &&
// XrmGetResource(db, name, name, &type, &ret) &&
// STREQ(type, "String") && *ret.addr != '\0')
// {
// return ret.addr;
// } else {
// return def;
// }
} }
void win_init(win_t *win) void win_init(win_t *win)
@ -156,6 +163,7 @@ void win_init(win_t *win)
f = win_res(db, BAR_FONT[0], BAR_FONT[1] ? BAR_FONT[1] : "monospace-8"); f = win_res(db, BAR_FONT[0], BAR_FONT[1] ? BAR_FONT[1] : "monospace-8");
win_init_font(e, f); win_init_font(e, f);
ellipsis_w = TEXTWIDTH(win, (char *)ellipsis, ELLIPSIS_LEN);
win->bar.l.buf = lbuf; win->bar.l.buf = lbuf;
win->bar.r.buf = rbuf; win->bar.r.buf = rbuf;
@ -410,7 +418,7 @@ void win_clear(win_t *win)
static int win_draw_text(win_t *win, XftDraw *d, const XftColor *color, static int win_draw_text(win_t *win, XftDraw *d, const XftColor *color,
int x, int y, char *text, int len, int w) int x, int y, char *text, int len, int w)
{ {
int err, tw = 0, warned = 0; int err, tw = 0, warned = 0, danger_zone = w - ellipsis_w;
char *t, *next; char *t, *next;
uint32_t rune; uint32_t rune;
XftFont *f; XftFont *f;
@ -437,6 +445,21 @@ static int win_draw_text(win_t *win, XftDraw *d, const XftColor *color,
FcCharSetDestroy(fccharset); FcCharSetDestroy(fccharset);
} }
XftTextExtentsUtf8(win->env.dpy, f, (XftChar8 *)t, next - t, &ext); XftTextExtentsUtf8(win->env.dpy, f, (XftChar8 *)t, next - t, &ext);
if (d != NULL && tw + ext.xOff >= danger_zone) {
int remaining_width = TEXTWIDTH(win, t, (text + len) - t);
if (tw + remaining_width > w) { /* overflow, print ellipsis */
if (tw + ellipsis_w <= w) {
win_draw_text(win, d, color, x, y, (char *)ellipsis,
ELLIPSIS_LEN, ellipsis_w);
tw += ellipsis_w;
}
if (f != font)
XftFontClose(win->env.dpy, f);
return tw;
}
/* text will fit, no need to check again on next iterations */
danger_zone = INT_MAX;
}
tw += ext.xOff; tw += ext.xOff;
if (tw <= w) { if (tw <= w) {
XftDrawStringUtf8(d, color, f, x, y, (XftChar8 *)t, next - t); XftDrawStringUtf8(d, color, f, x, y, (XftChar8 *)t, next - t);