Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hellpaper
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ CC = gcc
SRC = hellpaper.c

TARGET = hellpaper
CFLAGS = -Wall -O2
CFLAGS = -Wall -O3
LIBS = -lraylib -lm #-lGL -lpthread -ldl -lrt

PREFIX ?= /usr/local
Expand Down
26 changes: 26 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
inputs.nixpkgs.url = "github:nixos/nixpkgs";

outputs =
{ nixpkgs, ... }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
raylibWithJPG = pkgs.raylib.overrideAttrs (finalAttrs: {
cmakeFlags = finalAttrs.cmakeFlags ++ [ "-DSUPPORT_FILEFORMAT_JPG=ON" ];
});
in
{
devShells.${system}.default = pkgs.mkShell {
packages = [
raylibWithJPG
pkgs.pkg-config # For local compilation + linking with raylib
pkgs.bear # For generating compile_commands.json (used by LSPs)
];
};

packages.${system} = rec {
hellpaper = pkgs.stdenv.mkDerivation {
pname = "hellpaper";
version = "1.0.0";
src = ./.;

nativeBuildInputs = [ raylibWithJPG ];

buildPhase = ''
make
'';

installPhase = ''
mkdir -p $out/bin
mv ./hellpaper $out/bin/
'';

meta.mainProgram = "hellpaper";
};

default = hellpaper;
};
};
}
118 changes: 74 additions & 44 deletions hellpaper.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static Particle particles[MAX_POSSIBLE_PARTICLES];

static int wallpaper_count = 0;
static bool print_filename_only = false;
static bool recursive_traversal = false;

static atomic_int next_load_index = 0;
static atomic_bool loader_running = true;
Expand Down Expand Up @@ -387,9 +388,14 @@ static void LoadWallpapers(const char *dir)
struct dirent *entry;
while ((entry = readdir(dp)) != NULL && wallpaper_count < g_max_wallpapers)
{
if (entry->d_type != DT_REG)
bool is_dot_dir = (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0);
if (entry->d_type == DT_DIR && recursive_traversal && !is_dot_dir)
{
continue;
char *fullpath;
if (asprintf(&fullpath, "%s/%s", dir, entry->d_name) == -1) continue;
LoadWallpapers(fullpath);
} else if (entry->d_type != DT_REG) {
continue;
}
const char *ext = strrchr(entry->d_name, '.');
if (!ext || (strcasecmp(ext, ".jpg") != 0 && strcasecmp(ext, ".jpeg") != 0 && strcasecmp(ext, ".png") != 0))
Expand Down Expand Up @@ -507,48 +513,54 @@ void ParseConfigFile()

void print_help()
{
printf("Hellpaper - wallpaper picker for Linux.\n\n");
printf("USAGE:\n");
printf(" hellpaper [OPTIONS] [PATH]\n\n");
printf("ARGUMENTS:\n");
printf(" [PATH] Optional path to the directory containing wallpapers.\n");
printf(" Defaults to '~/Pictures/'.\n\n");
printf("OPTIONS:\n");
printf(" --help Show this help message and exit.\n");
printf(" --filename Print only the filename of the selected wallpaper to stdout.\n");
printf(" --width <pixels> Set the initial window width.\n");
printf(" --height <pixels> Set the initial window height.\n");
printf(" --startup-effect <effect>\n");
printf(" --keypress-effect <effect>\n");
printf(" --exit-effect <effect>\n");
printf(" Override the configured visual effects on certain events.\n");
printf(" Available effects: none, glitch, blur, pixelate, shake, collapse, reveal\n\n");
printf("KEYBINDINGS:\n");
printf(" NAVIGATION:\n");
printf(" h, j, k, l / Arrows Move selection. Keys repeat when held.\n");
printf(" Mouse Wheel Scroll through wallpapers.\n");
printf(" Ctrl + Mouse Wheel Zoom thumbnail scaling.\n\n");
printf(" ACTIONS:\n");
printf(" Enter / LMB Select the highlighted wallpaper and exit.\n");
printf(" L-Shift / RMB Show a full-screen preview of the highlighted wallpaper.\n");
printf(" / Enter search mode. Type to filter wallpapers by name.\n");
printf(" ESC Closes Preview, then Search, then the App.\n\n");
printf(" VIEW MODES:\n");
printf(" 1, 2, 3, 4 Switch between different layout modes:\n");
printf(" 1: Grid\n");
printf(" 2: Horizontal River\n");
printf(" 3: Vertical River\n");
printf(" 4: Wave\n\n");
printf("CONFIGURATION:\n");
printf(" Hellpaper can be fully customized by editing the configuration file located at:\n");
printf(" ~/.config/hellpaper/hellpaper.conf\n");
printf("Hellpaper - wallpaper picker for Linux.\n\n"
"USAGE:\n"
" hellpaper [OPTIONS] [PATH]\n\n"
"ARGUMENTS:\n"
" [PATH] Optional path to the directory containing wallpapers.\n"
" Defaults to '~/Pictures/'.\n\n"
"OPTIONS:\n"
" --help Show this help message and exit.\n"
" --filename Print only the filename of the selected wallpaper to stdout.\n"
" --recursive Recursively traverse the input directory for wallpapers.\n"
" --width <pixels> Set the initial window width.\n"
" --height <pixels> Set the initial window height.\n"
" --startup-effect <effect>\n"
" --keypress-effect <effect>\n"
" --exit-effect <effect>\n"
" Override the configured visual effects on certain events.\n"
" Available effects: none, glitch, blur, pixelate, shake, collapse, reveal\n\n"
"KEYBINDINGS:\n"
" NAVIGATION:\n"
" h, j, k, l / Arrows Move selection. Keys repeat when held.\n"
" q Quit application.\n"
" Mouse Wheel Scroll through wallpapers.\n"
" Ctrl + Mouse Wheel Zoom thumbnail scaling.\n\n"
" ACTIONS:\n"
" Enter / LMB Select the highlighted wallpaper and exit.\n"
" L-Shift / RMB Toggle a full-screen preview of the highlighted wallpaper.\n"
" / Enter search mode. Type to filter wallpapers by name.\n"
" ESC Closes Preview, then Search, then the App.\n\n"
" VIEW MODES:\n"
" 1, 2, 3, 4 Switch between different layout modes:\n"
" 1: Grid\n"
" 2: Horizontal River\n"
" 3: Vertical River\n"
" 4: Wave\n\n"
"CONFIGURATION:\n"
" Hellpaper can be fully customized by editing the configuration file located at:\n"
" ~/.config/hellpaper/hellpaper.conf\n");
}

void UpdateAndDrawScene(int filteredCount, int* filteredIndices, float delta, bool isPreviewing, bool isSearching)
{
int sw = GetScreenWidth();
int sh = GetScreenHeight();
Vector2 mouse = GetMousePosition();

Vector2 mouse_raw = GetMousePosition();
float scaleX = (float)GetRenderWidth() / (float)GetScreenWidth();
float scaleY = (float)GetRenderHeight() / (float)GetScreenHeight();
Vector2 mouse = (Vector2){ mouse_raw.x * scaleX, mouse_raw.y * scaleY };

if (g_modeTransitionTimer > 0)
{
Expand Down Expand Up @@ -743,6 +755,10 @@ int main(int argc, char **argv)
{
print_filename_only = true;
}
else if (strcmp(argv[i], "--recursive") == 0)
{
recursive_traversal = true;
}
else if (strcmp(argv[i], "--width") == 0 && i + 1 < argc)
{
g_win_width = atoi(argv[++i]);
Expand All @@ -763,7 +779,7 @@ int main(int argc, char **argv)
wallpaper_path = default_path;
}
LoadWallpapers(wallpaper_path);

SetConfigFlags(FLAG_WINDOW_HIGHDPI);
InitWindow(g_win_width, g_win_height, "Hellpaper");
SetExitKey(KEY_NULL);
SetTargetFPS(g_max_fps);
Expand Down Expand Up @@ -794,7 +810,7 @@ int main(int argc, char **argv)
TriggerEffect(g_startupEffect, 1.0f);

float keyRepeatTimer = 0.0f;
const float KEY_REPEAT_DELAY = 0.1f;
const float KEY_REPEAT_DELAY = 0.15f;

while (!WindowShouldClose())
{
Expand Down Expand Up @@ -881,15 +897,23 @@ int main(int argc, char **argv)
if (!blockActions)
{
int key = GetKeyPressed();
if (key != 0 && !isSearching)

// Process exit keycodes first
if ((key == KEY_Q || key == KEY_ESCAPE))
{
TriggerEffect(g_keypressEffect, 0.4f);
break;
}

if (key >= KEY_ONE && key < KEY_ONE + NUM_MODES)
{
g_targetMode = key - KEY_ONE;
g_modeTransitionTimer = g_modeTransitionDuration;
}

if (!isSearching)
{
TriggerEffect(g_keypressEffect, 0.4f);
}
}

bool ateEscKey = false;
Expand All @@ -909,7 +933,13 @@ int main(int argc, char **argv)
}
else
{
if (!blockActions && IsKeyPressed(KEY_SLASH)) { isSearching = true; searchBufferCount = 0; searchBuffer[0] = '\0'; }
if (!blockActions && IsKeyPressed(KEY_SLASH))
{
isSearching = true;
g_hoveredIndex = -1;
searchBufferCount = 0;
memset(searchBuffer, 0, 256);
}
}


Expand Down Expand Up @@ -1012,7 +1042,7 @@ int main(int argc, char **argv)
}
}

if (isPreviewing && (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) || IsKeyPressed(KEY_ESCAPE) || IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)))
if (isPreviewing && (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) || IsKeyPressed(KEY_ESCAPE) || IsKeyPressed(KEY_LEFT_SHIFT) || IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)))
{
if(IsKeyPressed(KEY_ESCAPE)) ateEscKey = true;
if (atomic_load(&isFullTextureReady)) UnloadTexture(fullPreviewTexture);
Expand Down