From c1db97f057e8f20aa26a2342da94eeff1d7a7725 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 20 Apr 2021 13:11:59 +0200 Subject: Proper atomic rename? also do not generate mipmap for manga --- src/AsyncImageLoader.cpp | 2 +- src/Body.cpp | 6 ----- src/DownloadUtils.cpp | 4 ++-- src/FileAnalyzer.cpp | 2 +- src/ImageViewer.cpp | 10 ++++---- src/QuickMedia.cpp | 12 +++++----- src/Storage.cpp | 62 ++++++++++++++---------------------------------- src/Tabs.cpp | 7 ++++-- 8 files changed, 38 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp index 1c676c1..34df062 100644 --- a/src/AsyncImageLoader.cpp +++ b/src/AsyncImageLoader.cpp @@ -24,7 +24,7 @@ namespace QuickMedia { const char *args[] = { "convert", thumbnail_path_first_frame.data.c_str(), "-thumbnail", new_size.c_str(), result_path_tmp.data.c_str(), nullptr}; int convert_res = exec_program(args, nullptr, nullptr); - if(convert_res == 0 && rename(result_path_tmp.data.c_str(), thumbnail_path_resized.data.c_str()) == 0) + if(convert_res == 0 && rename_atomic(result_path_tmp.data.c_str(), thumbnail_path_resized.data.c_str()) == 0) return true; else return false; diff --git a/src/Body.cpp b/src/Body.cpp index c008c40..dae0ca2 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -1038,9 +1038,6 @@ namespace QuickMedia { window.draw(loading_icon); text_offset_x += image_padding_x + content_size.x; } - } else if(merge_with_previous) { - // TODO: Get the previous items text_offset_x instead of + 32.0f * get_ui_scale() - text_offset_x += image_padding_x + (32.0f * get_ui_scale()); } else if(item->thumbnail_size.x > 0) { text_offset_x += image_padding_x + get_item_thumbnail_size(item).x; } @@ -1201,9 +1198,6 @@ namespace QuickMedia { } else { text_offset_x += image_padding_x + content_size.x; } - } else if(merge_with_previous) { - // TODO: Get the previous items text_offset_x instead of + 32.0f * get_ui_scale() - text_offset_x += image_padding_x + (32.0f * get_ui_scale()); } else if(item->thumbnail_size.x > 0) { text_offset_x += image_padding_x + get_item_thumbnail_size(item).x; } diff --git a/src/DownloadUtils.cpp b/src/DownloadUtils.cpp index e03bf5b..c773ce6 100644 --- a/src/DownloadUtils.cpp +++ b/src/DownloadUtils.cpp @@ -101,7 +101,7 @@ namespace QuickMedia { if(download_result == DownloadResult::OK) { Path media_file_path_tmp(media_file_path.data + ".tmp"); if(create_directory_recursive(media_dir) == 0 && file_overwrite(media_file_path_tmp, result) == 0) { - if(rename(media_file_path_tmp.data.c_str(), media_file_path.data.c_str()) != 0) { + if(rename_atomic(media_file_path_tmp.data.c_str(), media_file_path.data.c_str()) != 0) { perror("rename"); download_result = DownloadResult::ERR; } @@ -129,7 +129,7 @@ namespace QuickMedia { DownloadResult res = download_to_string(url, dummy, std::move(args), use_browser_useragent); if(res != DownloadResult::OK) return res; - if(rename(tmp_filepath.data.c_str(), destination_filepath.c_str()) != 0) { + if(rename_atomic(tmp_filepath.data.c_str(), destination_filepath.c_str()) != 0) { perror("rename"); return DownloadResult::ERR; } diff --git a/src/FileAnalyzer.cpp b/src/FileAnalyzer.cpp index 0059233..9f05919 100644 --- a/src/FileAnalyzer.cpp +++ b/src/FileAnalyzer.cpp @@ -135,7 +135,7 @@ namespace QuickMedia { } } - return rename(destination_path_tmp.data.c_str(), destination_path) == 0; + return rename_atomic(destination_path_tmp.data.c_str(), destination_path) == 0; } // TODO: Remove dependency on ffprobe diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp index dbd2284..56378ac 100644 --- a/src/ImageViewer.cpp +++ b/src/ImageViewer.cpp @@ -61,7 +61,7 @@ namespace QuickMedia { void ImageViewer::load_image_async(const Path &path, std::shared_ptr image_data) { image_data->image_status = ImageStatus::LOADING; - image_data->texture.setSmooth(true); + //image_data->texture.setSmooth(true); assert(!loading_image); loading_image = true; if(image_loader_thread.joinable()) @@ -174,13 +174,13 @@ namespace QuickMedia { // TODO: Add delay before checking again? if(get_file_type(image_path) == FileType::REGULAR) { - fprintf(stderr, "ImageViewer: Loaded page %d\n", 1 + page); + //fprintf(stderr, "ImageViewer: Loaded page %d\n", 1 + page); page_image_data = std::make_shared(); page_image_data->visible_on_screen = true; page_image_data->image_status = ImageStatus::WAITING; - page_image_data->texture.setSmooth(true); + //page_image_data->texture.setSmooth(true); } } @@ -294,7 +294,7 @@ namespace QuickMedia { if(page_data) { if(page_data->image_status == ImageStatus::LOADED && page_data->image->getSize().x > 0 && page_data->image->getSize().y > 0) { if(page_data->texture.loadFromImage(*page_data->image)) { - //page_data->texture.setSmooth(true); + page_data->texture.setSmooth(true); //page_data->texture.generateMipmap(); double height_before = get_page_size(page_i).y; page_data->image_status = ImageStatus::APPLIED_TO_TEXTURE; @@ -373,7 +373,7 @@ namespace QuickMedia { int i = 0; for(auto &page_data : image_data) { if(page_data && !page_data->visible_on_screen) { - fprintf(stderr, "ImageViewer: Unloaded page %d\n", 1 + i); + //fprintf(stderr, "ImageViewer: Unloaded page %d\n", 1 + i); page_data.reset(); loaded_textures_changed = true; } diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 37c5223..8d02b95 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -53,7 +53,7 @@ static const sf::Color back_color(21, 25, 30); static const std::string fourchan_google_captcha_api_key = "6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc"; static int FPS_IDLE = 2; static const double IDLE_TIMEOUT_SEC = 2.0; -static const sf::Vector2i AVATAR_THUMBNAIL_SIZE(std::floor(32 * QuickMedia::get_ui_scale()), std::floor(32 * QuickMedia::get_ui_scale())); +static const sf::Vector2i AVATAR_THUMBNAIL_SIZE(std::floor(32), std::floor(32)); static const std::pair valid_plugins[] = { std::make_pair("launcher", nullptr), @@ -563,12 +563,12 @@ namespace QuickMedia { if(exec_program(args, nullptr, nullptr) != 0) { fprintf(stderr, "Warning: failed to upscale %s with waifu2x-ncnn-vulkan\n", copy_op.source.data.c_str()); // No conversion, but we need the file to have the destination name to see that the operation completed (and read it) - if(rename(copy_op.source.data.c_str(), copy_op.destination.data.c_str()) != 0) + if(rename_atomic(copy_op.source.data.c_str(), copy_op.destination.data.c_str()) != 0) perror(tmp_file.data.c_str()); continue; } - if(rename(tmp_file.data.c_str(), copy_op.destination.data.c_str()) != 0) + if(rename_atomic(tmp_file.data.c_str(), copy_op.destination.data.c_str()) != 0) perror(tmp_file.data.c_str()); copy_op.destination.append(".upscaled"); @@ -2390,7 +2390,7 @@ namespace QuickMedia { if(load_image_from_file(image, image_path.data)) { if(image_texture.loadFromImage(image)) { image_texture.setSmooth(true); - image_texture.generateMipmap(); + //image_texture.generateMipmap(); return LoadImageResult::OK; } else { error_message = std::string("Failed to load image for page ") + std::to_string(image_index + 1); @@ -2509,7 +2509,7 @@ namespace QuickMedia { } if(rename_immediately) { - if(rename(image_filepath_tmp.data.c_str(), image_filepath.data.c_str()) != 0) { + if(rename_atomic(image_filepath_tmp.data.c_str(), image_filepath.data.c_str()) != 0) { perror(image_filepath_tmp.data.c_str()); show_notification("QuickMedia", "Failed to save image to file: " + image_filepath.data, Urgency::CRITICAL); return true; @@ -4951,7 +4951,7 @@ namespace QuickMedia { float room_name_padding_y = 0.0f; float padding_bottom = 0.0f; if(selected_tab == MESSAGES_TAB_INDEX || selected_tab == PINNED_TAB_INDEX) { - room_name_padding_y = 10.0f + room_name_total_height; + room_name_padding_y = std::floor(10.0f * get_ui_scale() + room_name_total_height); tab_vertical_offset = std::floor(10.0f * get_ui_scale()); } diff --git a/src/Storage.cpp b/src/Storage.cpp index 1e9f206..6a98267 100644 --- a/src/Storage.cpp +++ b/src/Storage.cpp @@ -1,5 +1,4 @@ #include "../include/Storage.hpp" -#include "../include/env.hpp" #include "../include/StringUtils.hpp" #include #include @@ -10,13 +9,11 @@ #include #include -#if OS_FAMILY == OS_FAMILY_POSIX #include #include #include #include #include -#endif static int makedir(const char *path) { return mkdir(path, S_IRWXU); @@ -25,7 +22,6 @@ static int makedir(const char *path) { namespace QuickMedia { Path get_home_dir() { - #if OS_FAMILY == OS_FAMILY_POSIX const char *homeDir = getenv("HOME"); if(!homeDir) { @@ -37,26 +33,6 @@ namespace QuickMedia { abort(); } return homeDir; - #elif OS_FAMILY == OS_FAMILY_WINDOWS - BOOL ret; - HANDLE hToken; - std::wstring homeDir; - DWORD homeDirLen = MAX_PATH; - homeDir.resize(homeDirLen); - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) - throw std::runtime_error("Failed to open process token"); - - if (!GetUserProfileDirectory(hToken, &homeDir[0], &homeDirLen)) - { - CloseHandle(hToken); - throw std::runtime_error("Failed to get home directory"); - } - - CloseHandle(hToken); - homeDir.resize(wcslen(homeDir.c_str())); - return boost::filesystem::path(homeDir); - #endif } Path get_storage_dir() { @@ -167,7 +143,7 @@ namespace QuickMedia { int res = file_overwrite(tmp_path, data.c_str(), data.size()); if(res != 0) return res; - return rename(tmp_path.data.c_str(), path.data.c_str()); + return rename_atomic(tmp_path.data.c_str(), path.data.c_str()); } void for_files_in_dir(const Path &path, FileIteratorCallback callback) { @@ -230,20 +206,8 @@ namespace QuickMedia { } bool save_json_to_file_atomic(const Path &path, const Json::Value &json) { - Path tmp_path = path; - tmp_path.append(".tmp"); - Json::StreamWriterBuilder json_builder; - if(file_overwrite(tmp_path, Json::writeString(json_builder, json)) != 0) - return false; - - // Rename is atomic under posix! - if(rename(tmp_path.data.c_str(), path.data.c_str()) != 0) { - perror("save_json_to_file_atomic rename"); - return false; - } - - return true; + return file_overwrite_atomic(path, Json::writeString(json_builder, json)) == 0; } bool save_json_to_file_atomic(const Path &path, const rapidjson::Value &json) { @@ -254,17 +218,27 @@ namespace QuickMedia { rapidjson::Writer writer(buffer); json.Accept(writer); - Json::StreamWriterBuilder json_builder; if(file_overwrite(tmp_path, buffer.GetString(), buffer.GetSize()) != 0) return false; - // Rename is atomic under posix! - if(rename(tmp_path.data.c_str(), path.data.c_str()) != 0) { - perror("save_json_to_file_atomic rename"); - return false; + return rename_atomic(tmp_path.data.c_str(), path.data.c_str()) == 0; + } + + int rename_atomic(const char *oldpath, const char *newpath) { + int fd = open(oldpath, O_RDONLY); + if(fd == -1) { + perror(oldpath); + return -1; } - return true; + if(fsync(fd) == -1) { + perror(oldpath); + close(fd); + return -1; + } + + close(fd); + return rename(oldpath, newpath); } bool is_program_executable_by_name(const char *name) { diff --git a/src/Tabs.cpp b/src/Tabs.cpp index 464ba4e..eb435fc 100644 --- a/src/Tabs.cpp +++ b/src/Tabs.cpp @@ -10,6 +10,7 @@ namespace QuickMedia { static const float tab_text_size = std::floor(16.0f * QuickMedia::get_ui_scale()); static const float tab_height = tab_text_size + std::floor(10.0f * QuickMedia::get_ui_scale()); static const sf::Color tab_selected_color(55, 60, 68); + static const sf::Color arrow_color(255, 255, 255, 175); static const float tab_min_width = 250.0f; static const float tab_margin_x = 10.0f; @@ -39,7 +40,7 @@ namespace QuickMedia { if(selected_tab > 0) { --selected_tab; float scroll_fixed = scroll + (tab_offset * width_per_tab); - if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width < 0.0f) + if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width < tab_margin_x) tab_offset++; if(on_change_tab) @@ -49,7 +50,7 @@ namespace QuickMedia { if(selected_tab < (int)tab_texts.size() - 1) { ++selected_tab; float scroll_fixed = scroll + (tab_offset * width_per_tab); - if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width > container_width) + if(scroll_fixed + tab_index_to_x_offset(selected_tab) + tab_background_width > container_width - tab_margin_x) tab_offset--; if(on_change_tab) @@ -139,6 +140,7 @@ namespace QuickMedia { window.draw(gradient_points, 4, sf::Quads); sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_ui_scale()), std::floor(2.0f * get_ui_scale()))); + line.setFillColor(arrow_color); line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f); line.rotate(-45.0f); @@ -165,6 +167,7 @@ namespace QuickMedia { window.draw(gradient_points, 4, sf::Quads); sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_ui_scale()), std::floor(2.0f * get_ui_scale()))); + line.setFillColor(arrow_color); line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f); line.rotate(45.0f); -- cgit v1.2.3