-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
blank-screens: rewrite with dynamic blanking support
- Loading branch information
Showing
10 changed files
with
672 additions
and
529 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
blank-screens |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
VPATH = src | ||
|
||
CXX := g++ | ||
|
||
warnings = -Wall -Wextra -Werror \ | ||
-Wswitch-default -Wfloat-equal \ | ||
-Wdisabled-optimization -Wsign-promo | ||
libs = -lX11 -lXrandr | ||
|
||
ifdef includeprefix | ||
include = -I$(includeprefix) | ||
else | ||
include = | ||
endif | ||
|
||
CXXFLAGS = $(warnings) -O3 -DNDEBUG -std=c++2c -pedantic -fpermissive $(include) | ||
LDFLAGS = $(libs) | ||
|
||
EXE = blank-screens | ||
|
||
SRC = $(shell find src -name "*.cpp") | ||
OBJ_ = $(SRC:src/%=%) | ||
OBJ = $(OBJ_:.cpp=.o) | ||
|
||
$(EXE): $(OBJ) | ||
$(CXX) $(LDFLAGS) $^ -o $(EXE) | ||
|
||
$(OBJ): %.o: %.cpp | ||
$(CXX) -c $(CXXFLAGS) $< -o $@ | ||
|
||
clean: | ||
rm -f -- $(OBJ) $(EXE) | ||
|
||
.PHONY: run clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#include "blind.hpp" | ||
|
||
#include <algorithm> | ||
|
||
#include <X11/Xatom.h> | ||
|
||
#include <xph/exec_info.hpp> | ||
|
||
bs::blind::blind(std::shared_ptr<bs::cli> cli, | ||
std::string_view monitor, | ||
Display* display, | ||
int default_screen, | ||
Window root_window, | ||
XRRCrtcInfo* crtc_info) | ||
: m_monitor(monitor) | ||
, m_cli(cli) | ||
, m_display(display) | ||
{ | ||
m_window = XCreateSimpleWindow(display, | ||
root_window, | ||
crtc_info->x, | ||
crtc_info->y, | ||
crtc_info->width, | ||
crtc_info->height, | ||
0, | ||
0, | ||
0); | ||
|
||
auto* class_hint = XAllocClassHint(); | ||
static std::string class_name(xph::exec_name); | ||
class_hint->res_name = class_name.data(); | ||
class_hint->res_class = class_name.data(); | ||
XSetClassHint(display, m_window, class_hint); | ||
|
||
XSetWindowAttributes window_attributes; | ||
window_attributes.override_redirect = True; | ||
|
||
const auto wm_state = XInternAtom(display, "_NET_WM_STATE", False); | ||
const auto wm_state_above = XInternAtom(display, "_NET_WM_STATE_ABOVE", False); | ||
const auto wm_window_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); | ||
const auto wm_window_type_dock = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DOCK", False); | ||
XChangeProperty(display, | ||
m_window, | ||
wm_state, | ||
XA_ATOM, | ||
32, | ||
PropModeAppend, | ||
reinterpret_cast<const unsigned char*>(&wm_state_above), | ||
1); | ||
XChangeProperty(display, | ||
m_window, | ||
wm_window_type, | ||
XA_ATOM, | ||
32, | ||
PropModeReplace, | ||
reinterpret_cast<const unsigned char*>(&wm_window_type), | ||
1); | ||
XChangeProperty(display, | ||
m_window, | ||
wm_window_type_dock, | ||
XA_ATOM, | ||
32, | ||
PropModeReplace, | ||
reinterpret_cast<const unsigned char*>(&wm_window_type_dock), | ||
1); | ||
|
||
XChangeWindowAttributes(display, m_window, CWOverrideRedirect, &window_attributes); | ||
|
||
XMapWindow(display, m_window); | ||
XRaiseWindow(display, m_window); | ||
XFlush(display); | ||
|
||
set_alpha(cli->alpha()); | ||
|
||
XSetWindowBackground(display, m_window, BlackPixel(display, default_screen)); | ||
XClearWindow(display, m_window); | ||
XFlush(display); | ||
} | ||
|
||
bs::blind::~blind(void) | ||
{ | ||
XDestroyWindow(m_display, m_window); | ||
XFlush(m_display); | ||
} | ||
|
||
void bs::blind::set_alpha(double alpha) | ||
{ | ||
alpha = std::clamp(alpha, m_cli->min_alpha(), m_cli->max_alpha()); | ||
|
||
unsigned long opacity; | ||
if (alpha > 1 - m_cli->snap_threshold()) | ||
opacity = 0xFFFFFFFFul; | ||
else if (alpha < m_cli->snap_threshold()) | ||
opacity = 0x00000000ul; | ||
else | ||
opacity = 0xFFFFFFFFul * alpha; | ||
|
||
const auto opacity_atom = XInternAtom(m_display, "_NET_WM_WINDOW_OPACITY", False); | ||
XChangeProperty(m_display, | ||
m_window, | ||
opacity_atom, | ||
XA_CARDINAL, | ||
32, | ||
PropModeReplace, | ||
reinterpret_cast<unsigned char*>(&opacity), | ||
1L); | ||
XFlush(m_display); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef HEADER_SCRIPTS_CXX_BS_BLIND_ | ||
#define HEADER_SCRIPTS_CXX_BS_BLIND_ | ||
|
||
#include <X11/extensions/Xrandr.h> | ||
|
||
#include "cli.hpp" | ||
|
||
namespace bs { | ||
class blind { | ||
public: | ||
std::string_view m_monitor; | ||
|
||
private: | ||
std::shared_ptr<cli> m_cli; | ||
Window m_window; | ||
Display* m_display; | ||
|
||
public: | ||
blind(void) = delete; | ||
~blind(void); | ||
blind(std::shared_ptr<cli> cli, | ||
std::string_view monitor, | ||
Display* display, | ||
int default_screen, | ||
Window root_window, | ||
XRRCrtcInfo* crtc_info); | ||
|
||
void set_alpha(double alpha); | ||
}; | ||
} // namespace bs | ||
|
||
#endif /* ifndef HEADER_SCRIPTS_CXX_BS_BLIND_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include "cli.hpp" | ||
|
||
#include <algorithm> | ||
#include <iostream> | ||
#include <limits> | ||
#include <vector> | ||
|
||
#include <cstdlib> | ||
|
||
#include <lyra/lyra.hpp> | ||
|
||
#include <xph/exec_info.hpp> | ||
|
||
bs::cli::cli(int argc, char** argv) | ||
{ | ||
bool show_help = false; | ||
double fps = 240; | ||
auto cli = | ||
lyra::cli() | lyra::help(show_help).description("Blank monitors.") | | ||
lyra::opt(m_alpha, "num")["-a"]["--alpha"]("set initial alpha of blinds") | | ||
lyra::opt(m_fifo_path, "path")["-c"]["--command-fifo"]("listen for commands on fifo") | | ||
lyra::opt(fps, "num")["-f"]["--fps"]("set frame rate of alpha interpolation") | | ||
lyra::opt(m_max_alpha, "num")["-H"]["--high"]("set upper alpha bound") | | ||
lyra::opt(m_min_alpha, "num")["-L"]["--low"]("set lower alpha bound") | | ||
lyra::opt(m_lock_path, "path")["-l"]["--lock"]("set lock path") | | ||
lyra::opt(m_ignore_primary)["-p"]["--ignore-primary"]("ignore primary monitor") | | ||
lyra::opt(m_snap_threshold, "num")["-s"]["--snap"]("set alpha snap threshold") | | ||
lyra::opt(m_lerp_factor, "num")["-t"]["--factor"]("set alpha linear interpolation factor") | | ||
lyra::arg(m_monitors, "monitor")("initial monitor to blank") | ||
.cardinality(0, std::numeric_limits<size_t>::max()); | ||
|
||
auto args = cli.parse({ argc, argv }); | ||
|
||
if (!args) { | ||
std::cerr << args.message() << '\n'; | ||
std::cerr << "Try '" << xph::exec_path << " -h' for more information.\n"; | ||
std::exit(EXIT_FAILURE); | ||
} | ||
|
||
if (show_help) { | ||
std::cout << cli << '\n'; | ||
std::exit(EXIT_SUCCESS); | ||
} | ||
|
||
m_frame_time = std::chrono::duration<double>{ 1.0 / fps }; | ||
|
||
std::sort(m_monitors.begin(), m_monitors.end()); | ||
m_monitors.erase(std::unique(m_monitors.begin(), m_monitors.end()), m_monitors.end()); | ||
} | ||
|
||
double bs::cli::alpha(void) const noexcept | ||
{ | ||
return m_alpha; | ||
} | ||
|
||
const std::string& bs::cli::fifo_path(void) const noexcept | ||
{ | ||
return m_fifo_path; | ||
} | ||
|
||
const std::chrono::duration<double>& bs::cli::frame_time(void) const noexcept | ||
{ | ||
return m_frame_time; | ||
} | ||
|
||
double bs::cli::max_alpha(void) const noexcept | ||
{ | ||
return m_max_alpha; | ||
} | ||
|
||
double bs::cli::min_alpha(void) const noexcept | ||
{ | ||
return m_min_alpha; | ||
} | ||
|
||
const std::string& bs::cli::lock_path(void) const noexcept | ||
{ | ||
return m_lock_path; | ||
} | ||
|
||
bool bs::cli::ignore_primary(void) const noexcept | ||
{ | ||
return m_ignore_primary; | ||
} | ||
|
||
double bs::cli::snap_threshold(void) const noexcept | ||
{ | ||
return m_snap_threshold; | ||
} | ||
|
||
double bs::cli::lerp_factor(void) const noexcept | ||
{ | ||
return m_lerp_factor; | ||
} | ||
|
||
const std::vector<std::string>& bs::cli::monitors(void) const noexcept | ||
{ | ||
return m_monitors; | ||
} | ||
|
||
namespace bs { | ||
std::ostream& operator<<(std::ostream& os, const bs::cli& cli) | ||
{ | ||
os << "alpha: " << cli.alpha() << '\n'; | ||
os << "fifo path: " << cli.fifo_path() << '\n'; | ||
os << "frame time: " << cli.frame_time().count() << '\n'; | ||
os << "max alpha: " << cli.max_alpha() << '\n'; | ||
os << "min alpha: " << cli.min_alpha() << '\n'; | ||
os << "lock path: " << cli.lock_path() << '\n'; | ||
os << "ignore primary: " << std::boolalpha << cli.ignore_primary() << '\n'; | ||
os << "snap threshold: " << cli.snap_threshold() << '\n'; | ||
os << "lerp factor: " << cli.lerp_factor() << '\n'; | ||
|
||
return os; | ||
} | ||
} // namespace bs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#ifndef HEADER_SCRIPTS_CXX_PAF_CLI_ | ||
#define HEADER_SCRIPTS_CXX_PAF_CLI_ | ||
|
||
#include <chrono> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace bs { | ||
class cli { | ||
public: | ||
static const constexpr double k_default_alpha = 1.0; | ||
static const constexpr double k_default_frame_rate = 100.0; | ||
static const constexpr double k_default_max_alpha = 1.0; | ||
static const constexpr double k_default_min_alpha = 0.0; | ||
static const constexpr double k_default_snap_threshold = 0.01; | ||
static const constexpr double k_default_lerp_factor = 0.10; | ||
static const constexpr char* const k_default_fifo_path = "/tmp/blank-screens/fifo"; | ||
static const constexpr char* const k_default_lock_path = "/tmp/blank-screens/"; | ||
|
||
private: | ||
double m_alpha = k_default_alpha; | ||
std::string m_fifo_path = k_default_fifo_path; | ||
std::chrono::duration<double> m_frame_time{ 1.0 / k_default_frame_rate }; | ||
double m_max_alpha = k_default_max_alpha; | ||
double m_min_alpha = k_default_min_alpha; | ||
std::string m_lock_path = k_default_lock_path; | ||
bool m_ignore_primary = false; | ||
double m_snap_threshold = k_default_snap_threshold; | ||
double m_lerp_factor = k_default_lerp_factor; | ||
std::vector<std::string> m_monitors; | ||
|
||
public: | ||
cli(void) = delete; | ||
cli(int argc, char** argv); | ||
|
||
double alpha(void) const noexcept; | ||
const std::string& fifo_path(void) const noexcept; | ||
const std::chrono::duration<double>& frame_time(void) const noexcept; | ||
double max_alpha(void) const noexcept; | ||
double min_alpha(void) const noexcept; | ||
const std::string& lock_path(void) const noexcept; | ||
bool ignore_primary(void) const noexcept; | ||
double snap_threshold(void) const noexcept; | ||
double lerp_factor(void) const noexcept; | ||
const std::vector<std::string>& monitors(void) const noexcept; | ||
|
||
friend std::ostream& operator<<(std::ostream& os, const cli& cli); | ||
}; | ||
} // namespace bs | ||
|
||
#endif /* ifndef HEADER_SCRIPTS_CXX_PAF_CLI_ */ |
Oops, something went wrong.