diff --git a/src/DrawingProgram/Tools/BrushTool.cpp b/src/DrawingProgram/Tools/BrushTool.cpp index b367d2f..e3a8bf2 100644 --- a/src/DrawingProgram/Tools/BrushTool.cpp +++ b/src/DrawingProgram/Tools/BrushTool.cpp @@ -176,7 +176,7 @@ bool BrushTool::prevent_undo_or_redo() { } void BrushTool::draw(SkCanvas* canvas, const DrawData& drawData) { - if(!drawP.world.main.input.isTouchDevice && !drawData.main->g.gui.cursor_obstructed()) { + if(!drawP.world.main.input.isTouchDevice && !drawData.main->g.gui.cursor_obstructed() && drawData.main->window.mouseFocus) { auto relativeWidthResult = drawP.world.main.toolConfig.get_relative_width_stroke_size(drawP, drawP.world.drawData.cam.c.inverseScale); if(relativeWidthResult.first.has_value()) { float width = relativeWidthResult.first.value(); diff --git a/src/DrawingProgram/Tools/EraserTool.cpp b/src/DrawingProgram/Tools/EraserTool.cpp index 389bc9b..dffb305 100644 --- a/src/DrawingProgram/Tools/EraserTool.cpp +++ b/src/DrawingProgram/Tools/EraserTool.cpp @@ -311,7 +311,7 @@ bool EraserTool::prevent_undo_or_redo() { } void EraserTool::draw(SkCanvas* canvas, const DrawData& drawData) { - if(!drawP.world.main.input.isTouchDevice && (!drawData.main->g.gui.cursor_obstructed() || isErasing) && !erasePath.isEmpty()) { + if(!drawP.world.main.input.isTouchDevice && (!drawData.main->g.gui.cursor_obstructed() || isErasing) && !erasePath.isEmpty() && drawData.main->window.mouseFocus) { if(isErasing) { CanvasComponentContainer::TransformData drawTransform = CanvasComponentContainer::calculate_draw_transform(drawData.cam.c, genData.coords); canvas->save(); diff --git a/src/GlobalConfig.cpp b/src/GlobalConfig.cpp index 279c71d..9c7a841 100644 --- a/src/GlobalConfig.cpp +++ b/src/GlobalConfig.cpp @@ -49,6 +49,7 @@ nlohmann::json GlobalConfig::get_config_json(const InputManager& input) const { toRet["guiScale"] = guiScale; toRet["jumpTransitionTime"] = jumpTransitionTime; toRet["mainCallbackRate"] = mainCallbackRate; + toRet["mainCallbackRateBackground"] = mainCallbackRateBackground; toRet["disableGraphicsDriverWorkarounds"] = disableGraphicsDriverWorkarounds; toRet["viewWebVersionWelcome"] = viewWebVersionWelcome; toRet["dragZoomSpeed"] = dragZoomSpeed; @@ -122,6 +123,7 @@ void GlobalConfig::set_config_json(InputManager& input, const nlohmann::json& j, try{j.at("dragZoomSpeed").get_to(dragZoomSpeed);} catch(...) {} try{j.at("scrollZoomSpeed").get_to(scrollZoomSpeed);} catch(...) {} try{j.at("mainCallbackRate").get_to(mainCallbackRate);} catch(...) {} + try{j.at("mainCallbackRateBackground").get_to(mainCallbackRateBackground);} catch(...) {} if(version >= VersionNumber(0, 6, 0)) try{j.at("vsync").get_to(vsyncValue);} catch(...) {} #ifndef __EMSCRIPTEN__ @@ -213,7 +215,3 @@ void GlobalConfig::load_licenses() { ownLicenseText = "InfiniPaint v" + VersionConstants::CURRENT_VERSION_STRING + "\n"; ownLicenseText += read_file_to_string("data/license"); } - -void GlobalConfig::update_main_loop_call_rate() { - SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, std::to_string(mainCallbackRate).c_str()); -} diff --git a/src/GlobalConfig.hpp b/src/GlobalConfig.hpp index 9c5af44..73ce541 100644 --- a/src/GlobalConfig.hpp +++ b/src/GlobalConfig.hpp @@ -74,6 +74,7 @@ class GlobalConfig { bool realTimeEraser = true; unsigned mainCallbackRate = 144; + unsigned mainCallbackRateBackground = 10; struct TabletOptions { bool pressureAffectsBrushWidth = true; @@ -94,7 +95,6 @@ class GlobalConfig { void save_palettes(); void load_palettes(); void load_licenses(); - void update_main_loop_call_rate(); bool checkForUpdates = true; bool useNativeFilePicker = true; diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index fef7c7f..aa9a8d6 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -540,6 +540,32 @@ void MainProgram::input_window_scale_callback(const InputManager::WindowScaleCal post_callback(); } +void MainProgram::input_window_mouse_focus_gained() { +#ifndef __ANDROID__ + update_main_loop_call_rate(conf.mainCallbackRate); +#endif +} + +void MainProgram::input_window_mouse_focus_lost() { +#ifndef __ANDROID__ + if(!window.mouseFocus && !window.windowFocus) + update_main_loop_call_rate(conf.mainCallbackRateBackground); +#endif +} + +void MainProgram::input_window_focus_gained() { +#ifndef __ANDROID__ + update_main_loop_call_rate(conf.mainCallbackRate); +#endif +} + +void MainProgram::input_window_focus_lost() { +#ifndef __ANDROID__ + if(!window.mouseFocus && !window.windowFocus) + update_main_loop_call_rate(conf.mainCallbackRateBackground); +#endif +} + std::optional MainProgram::get_text_box_start_info() { auto toRet = g.get_text_box_start_info(); if(toRet) @@ -552,6 +578,11 @@ void MainProgram::toggle_full_screen() { SDL_SetWindowFullscreen(window.sdlWindow, window.fullscreen); } +void MainProgram::update_main_loop_call_rate(unsigned newCallbackRate) { + std::cout << "New main callback rate: " << newCallbackRate << std::endl; + SDL_SetHint(SDL_HINT_MAIN_CALLBACK_RATE, std::to_string(newCallbackRate).c_str()); +} + void MainProgram::set_first_screen(std::unique_ptr firstScreen) { set_screen([&](std::unique_ptr){ return std::move(firstScreen); }); run_new_screen_func(); diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index c1eabdd..e06f8f0 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -83,6 +83,8 @@ class MainProgram { float density = 1.0f; float scale = 1.0f; + bool windowFocus = true; + bool mouseFocus = true; int defaultMSAASampleCount = 0; SkSurfaceProps defaultMSAASurfaceProps; @@ -139,6 +141,7 @@ class MainProgram { float get_scale_and_density_factor_gui(); bool app_close_requested(); void toggle_full_screen(); + void update_main_loop_call_rate(unsigned newCallbackRate); void set_first_screen(std::unique_ptr firstScreen); void set_screen(std::function(std::unique_ptr)> screenFunc); @@ -185,6 +188,10 @@ class MainProgram { void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion); void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w); void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w); + void input_window_mouse_focus_gained(); + void input_window_mouse_focus_lost(); + void input_window_focus_gained(); + void input_window_focus_lost(); std::optional get_text_box_start_info(); diff --git a/src/Screens/FileSelectScreen.cpp b/src/Screens/FileSelectScreen.cpp index b7034d6..7f7ce6d 100644 --- a/src/Screens/FileSelectScreen.cpp +++ b/src/Screens/FileSelectScreen.cpp @@ -1165,11 +1165,12 @@ void FileSelectScreen::settings_view() { }); input_scalar_field(gui, "FPS cap", "FPS Cap", &main.conf.mainCallbackRate, 10, 100000, { .onEdit = [&] { - main.conf.update_main_loop_call_rate(); + main.update_main_loop_call_rate(main.conf.mainCallbackRate); } }); checkbox_boolean_field(gui, "real time eraser", "Eraser works in real time", &main.conf.realTimeEraser); #ifndef __ANDROID__ + input_scalar_field(gui, "Background FPS cap", "Background FPS Cap", &main.conf.mainCallbackRateBackground, 1, 100000); checkbox_boolean_field(gui, "use mobile UI", "Use mobile UI (requires restart)", &main.conf.mobileUI); #endif #ifndef __EMSCRIPTEN__ @@ -1183,7 +1184,6 @@ void FileSelectScreen::settings_view() { void FileSelectScreen::about_view() { auto& gui = main.g.gui; - auto& io = gui.io; mainViewScrollArea = gui.element("about scroll area", ScrollArea::Options{ .scrollVertical = true, diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 3fc7933..efc6cd6 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -1554,9 +1554,10 @@ void Toolbar::general_settings_inner_gui() { }); input_scalar_field(gui, "FPS cap", "FPS Cap", &main.conf.mainCallbackRate, 10, 100000, { .onEdit = [&] { - main.conf.update_main_loop_call_rate(); + main.update_main_loop_call_rate(main.conf.mainCallbackRate); } }); + input_scalar_field(gui, "Background FPS cap", "Background FPS Cap", &main.conf.mainCallbackRateBackground, 1, 100000); #ifndef __EMSCRIPTEN__ checkbox_boolean_field(gui, "disable graphics driver workarounds", "Disable graphics driver workarounds (enabling or disabling this might fix some graphical glitches, requires restart)", &main.conf.disableGraphicsDriverWorkarounds); checkbox_boolean_field(gui, "apply display scale", "Apply display scale", &main.conf.applyDisplayScale); diff --git a/src/main.cpp b/src/main.cpp index fbd21f0..5bbbddc 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -362,8 +362,15 @@ void initialize_sdl(MainStruct& mS) { SDL_SyncWindow(mS.window); // Take maximize and fullscreen into account SDL_GetWindowSize(mS.window, &mS.m->window.size.x(), &mS.m->window.size.y()); + SDL_WindowFlags f = SDL_GetWindowFlags(mS.window); + mS.m->window.windowFocus = f & SDL_WINDOW_INPUT_FOCUS; + mS.m->window.mouseFocus = f & SDL_WINDOW_MOUSE_FOCUS; mS.m->input.update_safe_area(); - mS.m->conf.update_main_loop_call_rate(); +#ifndef __ANDROID__ + mS.m->update_main_loop_call_rate((mS.m->window.windowFocus || mS.m->window.mouseFocus) ? mS.m->conf.mainCallbackRate : mS.m->conf.mainCallbackRateBackground); +#else + mS.m->update_main_loop_call_rate(mS.m->conf.mainCallbackRate); +#endif } void sdl_terminate(MainStruct& mS) { @@ -813,6 +820,26 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { get_refresh_rate(mS); break; } + case SDL_EVENT_WINDOW_MOUSE_ENTER: { + mS.m->window.mouseFocus = true; + mS.m->input_window_mouse_focus_gained(); + break; + } + case SDL_EVENT_WINDOW_MOUSE_LEAVE: { + mS.m->window.mouseFocus = false; + mS.m->input_window_mouse_focus_lost(); + break; + } + case SDL_EVENT_WINDOW_FOCUS_GAINED: { + mS.m->window.windowFocus = true; + mS.m->input_window_focus_gained(); + break; + } + case SDL_EVENT_WINDOW_FOCUS_LOST: { + mS.m->window.windowFocus = false; + mS.m->input_window_focus_lost(); + break; + } case SDL_EVENT_SCREEN_KEYBOARD_SHOWN: break; case SDL_EVENT_SCREEN_KEYBOARD_HIDDEN: