aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-04-06 22:54:12 +0200
committerdec05eba <dec05eba@protonmail.com>2021-04-06 22:54:12 +0200
commitd3543b4f6d654cae1d1d9ffe1f640106dad5cfed (patch)
treee51f99400cb67dd8643393f82f2e10478750e7ba
parent04e852c45a3f309d5e139b0ca059b32277c250e4 (diff)
Add support for embedding the window into another application, such as suckless tabbed
-rw-r--r--README.md10
-rw-r--r--include/ImageViewer.hpp6
-rw-r--r--include/QuickMedia.hpp5
-rw-r--r--src/ImageViewer.cpp44
-rw-r--r--src/QuickMedia.cpp245
5 files changed, 178 insertions, 132 deletions
diff --git a/README.md b/README.md
index 98569a2..cb70613 100644
--- a/README.md
+++ b/README.md
@@ -6,18 +6,20 @@ Config data, including manga progress is stored under `$HOME/.config/quickmedia`
Cache is stored under `$HOME/.cache/quickmedia`.
## Usage
```
-usage: quickmedia <plugin> [--use-system-mpv-config] [--dir <directory>]
+usage: quickmedia <plugin> [--use-system-mpv-config] [--dir <directory>] [-e <window>]
OPTIONS:
plugin The plugin to use. Should be either launcher, 4chan, manganelo, mangatown, mangadex, youtube, spotify, soundcloud, nyaa.si, matrix, file-manager or stdin
--no-video Only play audio when playing a video. Disabled by default
--use-system-mpv-config Use system mpv config instead of no config. Disabled by default
--upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default
--upscale-images-always Upscale manga pages using waifu2x-ncnn-vulkan, no matter what the original image resolution is. Disabled by default
- --dir Set the start directory when using file-manager
+ --dir <directory> Set the start directory when using file-manager
+ -e <window> Embed QuickMedia into another window
EXAMPLES:
- quickmedia manganelo
+ quickmedia launcher
quickmedia --upscale-images-always manganelo
echo -e "hello\nworld" | quickmedia stdin
+ tabbed quickmedia launcher -e
```
## Installation
If you are running arch linux then you can install QuickMedia from aur (https://aur.archlinux.org/packages/quickmedia-git/), otherwise you will need to use [sibs](https://git.dec05eba.com/sibs/) to build QuickMedia manually.
@@ -74,6 +76,8 @@ Set `QM_PHONE_FACTOR=1` to disable the room list side panel in matrix.
Either set the `GDK_SCALE` environment variable or add `Xft.dpi` to `$HOME/.Xresources` (`xrdb` which is part of the `xorg-xrdb` package needs to be installed).\
For example a value of 96 for the `Xft.dpi` means 1.0 scaling and 144 (96*1.5) means 1.5 scaling.\
Note that at the moment, cached images will not be scaled with the dpi. Images do also not scale above their original size.
+## Tabs
+[tabbed](https://tools.suckless.org/tabbed/) can be used to put quickmedia windows into tabs. After installing `tabbed`, run `tabbed quickmedia launcher -e`.
# Dependencies
## Compile
See project.conf \[dependencies].
diff --git a/include/ImageViewer.hpp b/include/ImageViewer.hpp
index f886709..cd1bc8f 100644
--- a/include/ImageViewer.hpp
+++ b/include/ImageViewer.hpp
@@ -46,9 +46,9 @@ namespace QuickMedia {
class ImageViewer {
public:
- ImageViewer(MangaImagesPage *manga_images_page, const std::string &content_title, const std::string &chapter_title, int current_page, const Path &chapter_cache_dir);
+ ImageViewer(sf::RenderWindow *window, MangaImagesPage *manga_images_page, const std::string &content_title, const std::string &chapter_title, int current_page, const Path &chapter_cache_dir);
~ImageViewer();
- ImageViewerAction draw(sf::RenderWindow &window);
+ ImageViewerAction draw();
// Returns page as 1 indexed
int get_focused_page() const;
int get_num_pages() const { return num_pages; }
@@ -57,6 +57,8 @@ namespace QuickMedia {
bool render_page(sf::RenderWindow &window, int page, double offset_y);
sf::Vector2<double> get_page_size(int page);
private:
+ sf::RenderWindow *window;
+
int current_page;
int num_pages;
int page_center;
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index c6cd7b5..a8692bf 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -95,7 +95,9 @@ namespace QuickMedia {
void manga_get_watch_history(const char *plugin_name, BodyItems &history_items);
void youtube_get_watch_history(BodyItems &history_items);
private:
+ void init(Window parent_window);
void load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir);
+ void handle_window_close();
void base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_key_press = true, bool handle_searchbar = true);
void event_idle_handler(const sf::Event &event);
void idle_active_handler();
@@ -188,5 +190,8 @@ namespace QuickMedia {
bool idle = true;
bool low_cpu_mode = false;
std::string pipe_selected_text;
+ Window x11_window = None;
+ Atom wm_delete_window_atom;
+ XEvent xev;
};
} \ No newline at end of file
diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp
index 9297edf..85db360 100644
--- a/src/ImageViewer.cpp
+++ b/src/ImageViewer.cpp
@@ -11,7 +11,8 @@
#include <SFML/Graphics/RectangleShape.hpp>
namespace QuickMedia {
- ImageViewer::ImageViewer(MangaImagesPage *manga_images_page, const std::string &content_title, const std::string &chapter_title, int current_page, const Path &chapter_cache_dir) :
+ ImageViewer::ImageViewer(sf::RenderWindow *window, MangaImagesPage *manga_images_page, const std::string &content_title, const std::string &chapter_title, int current_page, const Path &chapter_cache_dir) :
+ window(window),
current_page(current_page),
num_pages(0),
content_title(content_title),
@@ -39,7 +40,8 @@ namespace QuickMedia {
}
ImageViewer::~ImageViewer() {
- // TODO: Remove
+ if(has_default_cursor)
+ window->setMouseCursor(default_cursor);
if(image_loader_thread.joinable())
image_loader_thread.join();
}
@@ -164,7 +166,7 @@ namespace QuickMedia {
return value >= 0.0 ? 1.0 : -1.0;
}
- ImageViewerAction ImageViewer::draw(sf::RenderWindow &window) {
+ ImageViewerAction ImageViewer::draw() {
const double frame_delta = frame_timer.restart().asSeconds();
const double scroll_speed_key_input = 50.0;
const double scroll_speed_mouse_wheel = 600.0;
@@ -172,7 +174,7 @@ namespace QuickMedia {
const double scroll_deaccel = 0.96;
if(!window_size_set) {
- auto window_size_i = window.getSize();
+ auto window_size_i = window->getSize();
window_size.x = window_size_i.x;
window_size.y = window_size_i.y;
window_size_set = true;
@@ -180,17 +182,12 @@ namespace QuickMedia {
// TODO: Only redraw when scrolling and when image has finished downloading
sf::Event event;
- while(window.pollEvent(event)) {
- if (event.type == sf::Event::Closed) {
- if(has_default_cursor)
- window.setMouseCursor(default_cursor);
- window.close();
- return ImageViewerAction::RETURN;
- } else if(event.type == sf::Event::Resized) {
+ while(window->pollEvent(event)) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
- window.setView(sf::View(visible_area));
+ window->setView(sf::View(visible_area));
//redraw = true;
} else if(event.type == sf::Event::GainedFocus) {
//redraw = true;
@@ -200,11 +197,8 @@ namespace QuickMedia {
if(event.key.code == sf::Keyboard::Down || (event.key.control && event.key.code == sf::Keyboard::J))
down_pressed = true;
- if(event.key.code == sf::Keyboard::Escape) {
- if(has_default_cursor)
- window.setMouseCursor(default_cursor);
+ if(event.key.code == sf::Keyboard::Escape)
return ImageViewerAction::RETURN;
- }
if(event.key.code == sf::Keyboard::I)
return ImageViewerAction::SWITCH_TO_SINGLE_IMAGE_MODE;
@@ -217,15 +211,15 @@ namespace QuickMedia {
scroll_speed += scroll_speed_mouse_wheel * event.mouseWheelScroll.delta * frame_delta;
} else if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Button::Middle) {
middle_mouse_scrolling = true;
- autoscroll_start_y = sf::Mouse::getPosition(window).y;
+ autoscroll_start_y = sf::Mouse::getPosition(*window).y;
if(has_size_vertical_cursor)
- window.setMouseCursor(size_vertical_cursor);
+ window->setMouseCursor(size_vertical_cursor);
} else if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Button::Middle) {
middle_mouse_scrolling = false;
scroll_speed = 0.0;
if(has_default_cursor)
- window.setMouseCursor(default_cursor);
+ window->setMouseCursor(default_cursor);
}
}
@@ -235,7 +229,7 @@ namespace QuickMedia {
scroll_speed -= scroll_speed_key_input * frame_delta;
if(middle_mouse_scrolling) {
- double distance_to_start_y = (double)sf::Mouse::getPosition(window).y - autoscroll_start_y;
+ double distance_to_start_y = (double)sf::Mouse::getPosition(*window).y - autoscroll_start_y;
double dist_abs = std::abs(distance_to_start_y);
dist_abs -= 20.0;
if(dist_abs < 0.0)
@@ -297,7 +291,7 @@ namespace QuickMedia {
}
const sf::Vector2<double> selected_page_size = get_page_size(current_page);
- render_page(window, current_page, window_size.y*0.5);
+ render_page(*window, current_page, window_size.y*0.5);
//if(!focused_page_rendered)
// return;
@@ -307,7 +301,7 @@ namespace QuickMedia {
while(true) {
const sf::Vector2<double> image_size = get_page_size(page);
page_offset -= image_size.y*0.5;
- if(!render_page(window, page, page_offset))
+ if(!render_page(*window, page, page_offset))
break;
--page;
page_offset -= image_size.y*0.5;
@@ -319,7 +313,7 @@ namespace QuickMedia {
while(true) {
const sf::Vector2<double> image_size = get_page_size(page);
page_offset += image_size.y*0.5;
- if(!render_page(window, page, page_offset))
+ if(!render_page(*window, page, page_offset))
break;
++page;
page_offset += image_size.y*0.5;
@@ -340,11 +334,11 @@ namespace QuickMedia {
sf::RectangleShape page_text_background(sf::Vector2f(window_size.x, background_height));
page_text_background.setFillColor(sf::Color(0, 0, 0, 150));
page_text_background.setPosition(0.0f, window_size.y - background_height);
- window.draw(page_text_background);
+ window->draw(page_text_background);
auto page_text_bounds = page_text.getLocalBounds();
page_text.setPosition(std::floor(window_size.x * 0.5f - page_text_bounds.width * 0.5f), std::floor(window_size.y - background_height * 0.5f - font_height * 0.5f));
- window.draw(page_text);
+ window->draw(page_text);
// Free pages that are not visible on the screen
int i = 0;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index c7d63d7..afd8461 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -395,74 +395,16 @@ namespace QuickMedia {
Program::Program() :
disp(nullptr),
- window(sf::VideoMode(1280, 720, 24), "QuickMedia", sf::Style::Default),
window_size(1280, 720),
current_page(PageType::EXIT),
image_index(0),
tab_background(sf::Vector2f(1.0f, 1.0f), 10.0f, 10)
{
- disp = XOpenDisplay(NULL);
- if (!disp)
- throw std::runtime_error("Failed to open display to X11 server");
-
- resources_root = "/usr/share/quickmedia/";
- if(get_file_type("../../../images/manganelo_logo.png") == FileType::REGULAR) {
- resources_root = "../../../";
- }
-
- set_resource_loader_root_path(resources_root.c_str());
-
- if(!circle_mask_shader.loadFromFile(resources_root + "shaders/circle_mask.glsl", sf::Shader::Type::Fragment)) {
- fprintf(stderr, "Failed to load %s/shaders/circle_mask.glsl", resources_root.c_str());
- abort();
- }
-
- if(!loading_icon.loadFromFile(resources_root + "images/loading_icon.png")) {
- fprintf(stderr, "Failed to load %s/images/loading_icon.png", resources_root.c_str());
- abort();
- }
- loading_icon.setSmooth(true);
- load_sprite.setTexture(loading_icon, true);
- sf::Vector2u loading_icon_size = loading_icon.getSize();
- load_sprite.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f);
-
- struct sigaction action;
- action.sa_handler = sigpipe_handler;
- sigemptyset(&action.sa_mask);
- action.sa_flags = 0;
- sigaction(SIGPIPE, &action, NULL);
-
- XSetErrorHandler(x_error_handler);
- XSetIOErrorHandler(x_io_error_handler);
-
- window.setVerticalSyncEnabled(true);
- monitor_hz = get_monitor_max_hz(disp);
- window.setFramerateLimit(FPS_IDLE);
- idle = true;
- vsync_set = false;
- /*
- if(enable_vsync(disp, window.getSystemHandle())) {
- vsync_set = true;
- } else {
- fprintf(stderr, "Failed to enable vsync, fallback to frame limiting\n");
- window.setFramerateLimit(monitor_hz);
- }
- */
- fprintf(stderr, "Monitor hz: %d\n", monitor_hz);
-
- if(create_directory_recursive(get_cache_dir().join("thumbnails")) != 0) {
- fprintf(stderr, "Failed to create thumbnails directory\n");
- }
-
- const char *qm_phone_factor = getenv("QM_PHONE_FACTOR");
- if(qm_phone_factor && atoi(qm_phone_factor) == 1)
- show_room_side_panel = false;
- else
- show_room_side_panel = true;
- main_thread_id = std::this_thread::get_id();
+
}
Program::~Program() {
+ window.close();
images_to_upscale_queue.close();
if(image_upscale_thead.joinable())
image_upscale_thead.join();
@@ -473,18 +415,20 @@ namespace QuickMedia {
}
static void usage() {
- fprintf(stderr, "usage: quickmedia <plugin> [--no-video] [--use-system-mpv-config] [--dir <directory>]\n");
+ fprintf(stderr, "usage: quickmedia <plugin> [--no-video] [--use-system-mpv-config] [--dir <directory>] [-e <window>]\n");
fprintf(stderr, "OPTIONS:\n");
fprintf(stderr, " plugin The plugin to use. Should be either launcher, 4chan, manganelo, mangatown, mangadex, pornhub, youtube, spotify, soundcloud, nyaa.si, matrix, file-manager or stdin\n");
fprintf(stderr, " --no-video Only play audio when playing a video. Disabled by default\n");
fprintf(stderr, " --use-system-mpv-config Use system mpv config instead of no config. Disabled by default\n");
fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n");
fprintf(stderr, " --upscale-images-always Upscale manga pages using waifu2x-ncnn-vulkan, no matter what the original image resolution is. Disabled by default\n");
- fprintf(stderr, " --dir Set the start directory when using file-manager\n");
+ fprintf(stderr, " --dir <directory> Set the start directory when using file-manager\n");
+ fprintf(stderr, " -e <window> Embed QuickMedia into another window\n");
fprintf(stderr, "EXAMPLES:\n");
- fprintf(stderr, " quickmedia manganelo\n");
+ fprintf(stderr, " quickmedia launcher\n");
fprintf(stderr, " quickmedia --upscale-images-always manganelo\n");
fprintf(stderr, " echo -e \"hello\\nworld\" | quickmedia stdin\n");
+ fprintf(stderr, " tabbed quickmedia launcher -e\n");
}
static bool is_manga_plugin(const char *plugin_name) {
@@ -508,6 +452,7 @@ namespace QuickMedia {
}
const char *start_dir = nullptr;
+ Window parent_window = None;
std::vector<Tab> tabs;
for(int i = 1; i < argc; ++i) {
@@ -539,6 +484,20 @@ namespace QuickMedia {
}
} else if(strcmp(argv[i], "--low-cpu-mode") == 0) {
low_cpu_mode = true;
+ } else if(strcmp(argv[i], "-e") == 0) {
+ if(i < argc - 1) {
+ parent_window = strtol(argv[i + 1], nullptr, 0);
+ if(parent_window == None && errno == EINVAL) {
+ fprintf(stderr, "Invalid -e argument. Argument has to be a number\n");
+ usage();
+ return -1;
+ }
+ ++i;
+ } else {
+ fprintf(stderr, "Missing window to embed into after -e argument\n");
+ usage();
+ return -1;
+ }
} else if(argv[i][0] == '-') {
fprintf(stderr, "Invalid option %s\n", argv[i]);
usage();
@@ -546,17 +505,17 @@ namespace QuickMedia {
}
}
- if(low_cpu_mode)
- FPS_IDLE = 2;
- else
- FPS_IDLE = 20;
-
if(!plugin_name) {
fprintf(stderr, "Missing plugin argument\n");
usage();
return -1;
}
+ if(low_cpu_mode)
+ FPS_IDLE = 2;
+ else
+ FPS_IDLE = 20;
+
if(upscale_image_action != UpscaleImageAction::NO) {
if(!is_manga_plugin(plugin_name)) {
fprintf(stderr, "Option --upscale-images/-upscale-images-force is only valid for manganelo, mangatown and mangadex\n");
@@ -605,6 +564,7 @@ namespace QuickMedia {
return -1;
}
+ init(parent_window);
load_plugin_by_name(tabs, start_dir);
while(!tabs.empty() || matrix) {
@@ -632,16 +592,99 @@ namespace QuickMedia {
return exit_code;
}
+ void Program::init(Window parent_window) {
+ disp = XOpenDisplay(NULL);
+ if (!disp)
+ throw std::runtime_error("Failed to open display to X11 server");
+
+ wm_delete_window_atom = XInternAtom(disp, "WM_DELETE_WINDOW", False);
+
+ int screen = DefaultScreen(disp);
+ int screen_center_x = (DisplayWidth(disp, screen) - window_size.x) / 2;
+ int screen_center_y = (DisplayHeight(disp, screen) - window_size.y) / 2;
+
+ x11_window = XCreateWindow(disp, parent_window ? parent_window : DefaultRootWindow(disp),
+ screen_center_x, screen_center_y, window_size.x, window_size.y, 0,
+ DefaultDepth(disp, screen),
+ InputOutput,
+ DefaultVisual(disp, screen),
+ 0, nullptr);
+ if(!x11_window)
+ throw std::runtime_error("Failed to create window");
+
+ XStoreName(disp, x11_window, "QuickMedia");
+ XMapWindow(disp, x11_window);
+ XFlush(disp);
+
+ window.create(x11_window);
+
+ resources_root = "/usr/share/quickmedia/";
+ if(get_file_type("../../../images/manganelo_logo.png") == FileType::REGULAR) {
+ resources_root = "../../../";
+ }
+
+ set_resource_loader_root_path(resources_root.c_str());
+
+ if(!circle_mask_shader.loadFromFile(resources_root + "shaders/circle_mask.glsl", sf::Shader::Type::Fragment)) {
+ fprintf(stderr, "Failed to load %s/shaders/circle_mask.glsl", resources_root.c_str());
+ abort();
+ }
+
+ if(!loading_icon.loadFromFile(resources_root + "images/loading_icon.png")) {
+ fprintf(stderr, "Failed to load %s/images/loading_icon.png", resources_root.c_str());
+ abort();
+ }
+ loading_icon.setSmooth(true);
+ load_sprite.setTexture(loading_icon, true);
+ sf::Vector2u loading_icon_size = loading_icon.getSize();
+ load_sprite.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f);
+
+ struct sigaction action;
+ action.sa_handler = sigpipe_handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ sigaction(SIGPIPE, &action, NULL);
+
+ XSetErrorHandler(x_error_handler);
+ XSetIOErrorHandler(x_io_error_handler);
+
+ window.setVerticalSyncEnabled(true);
+ monitor_hz = get_monitor_max_hz(disp);
+ window.setFramerateLimit(FPS_IDLE);
+ idle = true;
+ vsync_set = false;
+ /*
+ if(enable_vsync(disp, window.getSystemHandle())) {
+ vsync_set = true;
+ } else {
+ fprintf(stderr, "Failed to enable vsync, fallback to frame limiting\n");
+ window.setFramerateLimit(monitor_hz);
+ }
+ */
+ fprintf(stderr, "Monitor hz: %d\n", monitor_hz);
+
+ if(create_directory_recursive(get_cache_dir().join("thumbnails")) != 0)
+ throw std::runtime_error("Failed to create thumbnails directory");
+
+ const char *qm_phone_factor = getenv("QM_PHONE_FACTOR");
+ if(qm_phone_factor && atoi(qm_phone_factor) == 1)
+ show_room_side_panel = false;
+ else
+ show_room_side_panel = true;
+ main_thread_id = std::this_thread::get_id();
+ }
+
void Program::load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir) {
if(!plugin_name || plugin_name[0] == '\0')
return;
window.setTitle("QuickMedia - " + std::string(plugin_name));
- const char *plugin_logo_name = get_plugin_logo_name(plugin_name);
+ no_video = force_no_video;
+
std::string plugin_logo_path;
+ const char *plugin_logo_name = get_plugin_logo_name(plugin_name);
if(plugin_logo_name)
plugin_logo_path = resources_root + "images/" + plugin_logo_name;
- no_video = force_no_video;
plugin_logo = sf::Texture();
if(!plugin_logo_path.empty()) {
@@ -744,11 +787,15 @@ namespace QuickMedia {
}
}
- void Program::base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_keypress, bool handle_searchbar) {
- if (event.type == sf::Event::Closed) {
+ void Program::handle_window_close() {
+ if(wm_delete_window_atom && XCheckTypedWindowEvent(disp, x11_window, ClientMessage, &xev) && (Atom)xev.xclient.data.l[0] == wm_delete_window_atom) {
current_page = PageType::EXIT;
window.close();
- } else if(event.type == sf::Event::Resized) {
+ }
+ }
+
+ void Program::base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_keypress, bool handle_searchbar) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -1087,14 +1134,13 @@ namespace QuickMedia {
}
void Program::page_loop(std::vector<Tab> &tabs, int start_tab_index, PageLoopSubmitHandler after_submit_handler) {
- malloc_trim(0);
-
if(tabs.empty()) {
show_notification("QuickMedia", "No tabs provided!", Urgency::CRITICAL);
return;
}
window.setFramerateLimit(FPS_IDLE);
+ malloc_trim(0);
idle = true;
for(Tab &tab : tabs) {
@@ -1318,9 +1364,7 @@ namespace QuickMedia {
else
event_idle_handler(event);
- if (event.type == sf::Event::Closed) {
- window.close();
- } else if(event.type == sf::Event::Resized) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -1416,6 +1460,7 @@ namespace QuickMedia {
}
}
update_idle_state();
+ handle_window_close();
if(redraw) {
redraw = false;
@@ -1711,12 +1756,7 @@ namespace QuickMedia {
sf::Event event;
while(window.isOpen()) {
while(window.pollEvent(event)) {
- if(event.type == sf::Event::Closed) {
- task.cancel();
- current_page = PageType::EXIT;
- window.close();
- return TaskResult::CANCEL;
- } else if(event.type == sf::Event::Resized) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -1727,6 +1767,13 @@ namespace QuickMedia {
}
}
+ if(wm_delete_window_atom && XCheckTypedWindowEvent(disp, x11_window, ClientMessage, &xev) && (Atom)xev.xclient.data.l[0] == wm_delete_window_atom) {
+ task.cancel();
+ current_page = PageType::EXIT;
+ window.close();
+ return TaskResult::CANCEL;
+ }
+
if(task.ready()) {
if(task.get())
return TaskResult::TRUE;
@@ -1953,10 +2000,7 @@ namespace QuickMedia {
while (current_page == PageType::VIDEO_CONTENT && window.isOpen()) {
while (window.pollEvent(event)) {
- if (event.type == sf::Event::Closed) {
- current_page = PageType::EXIT;
- window.close();
- } else if(event.type == sf::Event::Resized) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -1968,6 +2012,7 @@ namespace QuickMedia {
save_video_url_to_clipboard();
}
}
+ handle_window_close();
if(video_player_window && XCheckTypedWindowEvent(disp, video_player_window, KeyPress, &xev)/* && xev.xkey.subwindow == video_player_window*/) {
#pragma GCC diagnostic push
@@ -2448,10 +2493,7 @@ namespace QuickMedia {
// TODO: Show to user if a certain page is missing (by checking page name (number) and checking if some are skipped)
while (current_page == PageType::IMAGES && window.isOpen()) {
while(window.pollEvent(event)) {
- if (event.type == sf::Event::Closed) {
- current_page = PageType::EXIT;
- window.close();
- } else if(event.type == sf::Event::Resized) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -2487,6 +2529,7 @@ namespace QuickMedia {
}
}
}
+ handle_window_close();
if(download_in_progress && check_downloaded_timer.getElapsedTime().asMilliseconds() >= check_downloaded_timeout_ms) {
sf::String error_msg;
@@ -2604,7 +2647,7 @@ namespace QuickMedia {
json_chapter = Json::Value(Json::objectValue);
}
- ImageViewer image_viewer(images_page, images_page->manga_name, images_page->get_chapter_name(), image_index, content_cache_dir);
+ ImageViewer image_viewer(&window, images_page, images_page->manga_name, images_page->get_chapter_name(), image_index, content_cache_dir);
json_chapter["current"] = std::min(latest_read, image_viewer.get_num_pages());
json_chapter["total"] = image_viewer.get_num_pages();
@@ -2616,8 +2659,9 @@ namespace QuickMedia {
window.setFramerateLimit(monitor_hz);
while(current_page == PageType::IMAGES_CONTINUOUS && window.isOpen()) {
+ handle_window_close();
window.clear(back_color);
- ImageViewerAction action = image_viewer.draw(window);
+ ImageViewerAction action = image_viewer.draw();
switch(action) {
case ImageViewerAction::NONE:
break;
@@ -2850,10 +2894,7 @@ namespace QuickMedia {
}
}
- if(event.type == sf::Event::Closed) {
- current_page = PageType::EXIT;
- window.close();
- } else if(event.type == sf::Event::Resized) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -3016,6 +3057,7 @@ namespace QuickMedia {
}
frame_skip_text_entry = false;
update_idle_state();
+ handle_window_close();
chat_input_height_full = comment_input.get_height() + chat_input_padding_y * 2.0f;
@@ -3195,10 +3237,7 @@ namespace QuickMedia {
else
event_idle_handler(event);
- if (event.type == sf::Event::Closed) {
- current_page = PageType::EXIT;
- window.close();
- } else if(event.type == sf::Event::Resized) {
+ if(event.type == sf::Event::Resized) {
window_size.x = event.size.width;
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
@@ -3217,6 +3256,7 @@ namespace QuickMedia {
inputs[focused_input]->on_event(event);
}
update_idle_state();
+ handle_window_close();
if(redraw) {
redraw = false;
@@ -4690,6 +4730,7 @@ namespace QuickMedia {
}
frame_skip_text_entry = false;
update_idle_state();
+ handle_window_close();
matrix_chat_page->update();