From d3543b4f6d654cae1d1d9ffe1f640106dad5cfed Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 6 Apr 2021 22:54:12 +0200 Subject: Add support for embedding the window into another application, such as suckless tabbed --- README.md | 10 +- include/ImageViewer.hpp | 6 +- include/QuickMedia.hpp | 5 + src/ImageViewer.cpp | 44 ++++----- src/QuickMedia.cpp | 245 ++++++++++++++++++++++++++++-------------------- 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 [--use-system-mpv-config] [--dir ] +usage: quickmedia [--use-system-mpv-config] [--dir ] [-e ] 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 Set the start directory when using file-manager + -e 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 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 &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 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 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 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 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 [--no-video] [--use-system-mpv-config] [--dir ]\n"); + fprintf(stderr, "usage: quickmedia [--no-video] [--use-system-mpv-config] [--dir ] [-e ]\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 Set the start directory when using file-manager\n"); + fprintf(stderr, " -e 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 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 &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 &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(); -- cgit v1.2.3