mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-01 01:20:25 +00:00
[win] Fix sync between mouse cursor <-> stylus cursor (fix #4539)
Added a new option (enabled by default) to set the mouse cursor when a pen/pointer message is received. This fixes a couple of issues: 1) When we zoom in/out with keys or scrolling the trackpad, the last known position will be used (the pen position if we are using the pen). 2) If we are recording the stream/live streaming with a software like OBS Studio, the cursor position will correctly be in the pen position if we're painting with the pen.
This commit is contained in:
parent
2827618786
commit
f29ec83c6c
@ -230,6 +230,7 @@
|
|||||||
</section>
|
</section>
|
||||||
<section id="tablet" text="Tablet">
|
<section id="tablet" text="Tablet">
|
||||||
<option id="api" type="std::string" />
|
<option id="api" type="std::string" />
|
||||||
|
<option id="set_cursor_fix" type="bool" default="true" />
|
||||||
</section>
|
</section>
|
||||||
<section id="experimental" text="Experimental">
|
<section id="experimental" text="Experimental">
|
||||||
<option id="multiple_windows" type="bool" default="false" />
|
<option id="multiple_windows" type="bool" default="false" />
|
||||||
|
@ -1504,10 +1504,11 @@ native_file_dialog = Use native file dialog
|
|||||||
shaders_for_color_selectors = Use shaders for color selectors
|
shaders_for_color_selectors = Use shaders for color selectors
|
||||||
hue_with_sat_value = Apply Saturation/Value to Hue slider on Tint/Shade/Tone selector
|
hue_with_sat_value = Apply Saturation/Value to Hue slider on Tint/Shade/Tone selector
|
||||||
cache_compressed_tilesets = Cache compressed tilesets for faster save (uses more memory)
|
cache_compressed_tilesets = Cache compressed tilesets for faster save (uses more memory)
|
||||||
|
windows_pointer = Windows Pointer options
|
||||||
one_finger_as_mouse_movement = Interpret one finger as mouse movement
|
one_finger_as_mouse_movement = Interpret one finger as mouse movement
|
||||||
one_finger_as_mouse_movement_tooltip = Only for Windows 8/10 Pointer API: Interprets one finger as mouse movement\nand two fingers as pan/scroll. Uncheck this to use the old behavior:\nOne finger pans/scrolls
|
one_finger_as_mouse_movement_tooltip = Interprets one finger as mouse movement and two fingers as pan/scroll.\nUncheck this to use the old behavior: one finger pans/scrolls
|
||||||
load_wintab_driver = Load wintab32 library
|
set_cursor_fix = Set cursor position from stylus location
|
||||||
load_wintab_driver_tooltip = Loads wintab32.dll driver to use Wacom-like devices\nwhen Aseprite is started
|
set_cursor_fix_tooltip = Sets the mouse position to the pen location when\nyou have two pointers available (e.g. mouse and pen)\n\nUseful to zoom in/out from the pen position and to get the\ncorrect cursor location when screencasting/live streaming.
|
||||||
wintab_more_info = (More Information)
|
wintab_more_info = (More Information)
|
||||||
flash_selected_layer = Flash layer when it is selected
|
flash_selected_layer = Flash layer when it is selected
|
||||||
non_active_layer_opacity = Opacity for non-active layers:
|
non_active_layer_opacity = Opacity for non-active layers:
|
||||||
|
@ -95,19 +95,25 @@
|
|||||||
<vbox id="section_tablet">
|
<vbox id="section_tablet">
|
||||||
<separator text="@.section_tablet" horizontal="true" />
|
<separator text="@.section_tablet" horizontal="true" />
|
||||||
<radio id="tablet_api_windows_pointer" text="@.tablet_api_windows_pointer" group="1" />
|
<radio id="tablet_api_windows_pointer" text="@.tablet_api_windows_pointer" group="1" />
|
||||||
<radio id="tablet_api_wintab_system" text="@.tablet_api_wintab_system" group="1" />
|
|
||||||
<radio id="tablet_api_wintab_direct" text="@.tablet_api_wintab_direct" group="1" />
|
|
||||||
<separator horizontal="true" />
|
|
||||||
<check id="one_finger_as_mouse_movement"
|
|
||||||
text="@.one_finger_as_mouse_movement"
|
|
||||||
tooltip="@.one_finger_as_mouse_movement_tooltip"
|
|
||||||
pref="experimental.one_finger_as_mouse_movement" />
|
|
||||||
<hbox>
|
<hbox>
|
||||||
<check id="load_wintab_driver"
|
<radio id="tablet_api_wintab_system" text="@.tablet_api_wintab_system" group="1" />
|
||||||
text="@.load_wintab_driver"
|
|
||||||
tooltip="@.load_wintab_driver_tooltip" />
|
|
||||||
<link text="@.wintab_more_info" url="https://www.aseprite.org/docs/wintab/" />
|
<link text="@.wintab_more_info" url="https://www.aseprite.org/docs/wintab/" />
|
||||||
</hbox>
|
</hbox>
|
||||||
|
<radio id="tablet_api_wintab_direct" text="@.tablet_api_wintab_direct" group="1" />
|
||||||
|
<vbox id="windows_pointer_options">
|
||||||
|
<separator text="@.windows_pointer" horizontal="true" />
|
||||||
|
<check id="one_finger_as_mouse_movement"
|
||||||
|
text="@.one_finger_as_mouse_movement"
|
||||||
|
tooltip="@.one_finger_as_mouse_movement_tooltip"
|
||||||
|
pref="experimental.one_finger_as_mouse_movement" />
|
||||||
|
<hbox>
|
||||||
|
<check id="set_cursor_fix"
|
||||||
|
text="@.set_cursor_fix"
|
||||||
|
tooltip="@.set_cursor_fix_tooltip"
|
||||||
|
pref="tablet.set_cursor_fix" />
|
||||||
|
<link text="(#4539)" url="https://github.com/aseprite/aseprite/issues/4539" />
|
||||||
|
</hbox>
|
||||||
|
</vbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
||||||
<!-- Files -->
|
<!-- Files -->
|
||||||
@ -575,12 +581,6 @@
|
|||||||
<check id="tint_shade_tone_hue_with_sat_value"
|
<check id="tint_shade_tone_hue_with_sat_value"
|
||||||
text="@.hue_with_sat_value"
|
text="@.hue_with_sat_value"
|
||||||
pref="experimental.hue_with_sat_value_for_color_selector" />
|
pref="experimental.hue_with_sat_value_for_color_selector" />
|
||||||
<hbox id="load_wintab_driver_box">
|
|
||||||
<check id="load_wintab_driver2"
|
|
||||||
text="@.load_wintab_driver"
|
|
||||||
tooltip="@.load_wintab_driver_tooltip" />
|
|
||||||
<link text="@.wintab_more_info" url="https://www.aseprite.org/docs/wintab/" />
|
|
||||||
</hbox>
|
|
||||||
<check id="flash_layer" text="@.flash_selected_layer" />
|
<check id="flash_layer" text="@.flash_selected_layer" />
|
||||||
<hbox>
|
<hbox>
|
||||||
<label text="@.non_active_layer_opacity" />
|
<label text="@.non_active_layer_opacity" />
|
||||||
|
2
laf
2
laf
@ -1 +1 @@
|
|||||||
Subproject commit feba52e4ca7855219044e9fdf936ecb6b9b4d1ca
|
Subproject commit ff41af60e95517fa9e922374c9a3a43442bce5b4
|
@ -283,27 +283,34 @@ int App::initialize(const AppOptions& options)
|
|||||||
m_isShell = options.startShell();
|
m_isShell = options.startShell();
|
||||||
m_coreModules = std::make_unique<CoreModules>();
|
m_coreModules = std::make_unique<CoreModules>();
|
||||||
|
|
||||||
|
auto& pref = preferences();
|
||||||
|
|
||||||
#if LAF_WINDOWS
|
#if LAF_WINDOWS
|
||||||
|
|
||||||
|
os::TabletOptions tabletOptions;
|
||||||
if (options.disableWintab() ||
|
if (options.disableWintab() ||
|
||||||
!preferences().experimental.loadWintabDriver() ||
|
!pref.experimental.loadWintabDriver() ||
|
||||||
preferences().tablet.api() == "pointer") {
|
pref.tablet.api() == "pointer") {
|
||||||
system->setTabletAPI(os::TabletAPI::WindowsPointerInput);
|
tabletOptions.api = os::TabletAPI::WindowsPointerInput;
|
||||||
}
|
}
|
||||||
else if (preferences().tablet.api() == "wintab_packets")
|
else if (pref.tablet.api() == "wintab_packets") {
|
||||||
system->setTabletAPI(os::TabletAPI::WintabPackets);
|
tabletOptions.api = os::TabletAPI::WintabPackets;
|
||||||
else // preferences().tablet.api() == "wintab"
|
}
|
||||||
system->setTabletAPI(os::TabletAPI::Wintab);
|
else { // pref.tablet.api() == "wintab"
|
||||||
|
tabletOptions.api = os::TabletAPI::Wintab;
|
||||||
|
}
|
||||||
|
tabletOptions.setCursorFix = pref.tablet.setCursorFix();
|
||||||
|
system->setTabletOptions(tabletOptions);
|
||||||
|
|
||||||
#elif LAF_MACOS
|
#elif LAF_MACOS
|
||||||
|
|
||||||
if (!preferences().general.osxAsyncView())
|
if (!pref.general.osxAsyncView())
|
||||||
os::osx_set_async_view(false);
|
os::osx_set_async_view(false);
|
||||||
|
|
||||||
#elif LAF_LINUX
|
#elif LAF_LINUX
|
||||||
|
|
||||||
{
|
{
|
||||||
const std::string& stylusId = preferences().general.x11StylusId();
|
const std::string& stylusId = pref.general.x11StylusId();
|
||||||
if (!stylusId.empty())
|
if (!stylusId.empty())
|
||||||
os::x11_set_user_defined_string_to_detect_stylus(stylusId);
|
os::x11_set_user_defined_string_to_detect_stylus(stylusId);
|
||||||
}
|
}
|
||||||
@ -331,7 +338,7 @@ int App::initialize(const AppOptions& options)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize_color_spaces(preferences());
|
initialize_color_spaces(pref);
|
||||||
|
|
||||||
#ifdef ENABLE_DRM
|
#ifdef ENABLE_DRM
|
||||||
LOG("APP: Initializing DRM...\n");
|
LOG("APP: Initializing DRM...\n");
|
||||||
@ -344,14 +351,14 @@ int App::initialize(const AppOptions& options)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Load modules
|
// Load modules
|
||||||
m_modules = std::make_unique<Modules>(createLogInDesktop, preferences());
|
m_modules = std::make_unique<Modules>(createLogInDesktop, pref);
|
||||||
m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE: 0);
|
m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE: 0);
|
||||||
#ifdef ENABLE_UI
|
#ifdef ENABLE_UI
|
||||||
m_brushes = std::make_unique<AppBrushes>();
|
m_brushes = std::make_unique<AppBrushes>();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Data recovery is enabled only in GUI mode
|
// Data recovery is enabled only in GUI mode
|
||||||
if (isGui() && preferences().general.dataRecovery())
|
if (isGui() && pref.general.dataRecovery())
|
||||||
m_modules->createDataRecovery(context());
|
m_modules->createDataRecovery(context());
|
||||||
|
|
||||||
if (isPortable())
|
if (isPortable())
|
||||||
@ -371,8 +378,8 @@ int App::initialize(const AppOptions& options)
|
|||||||
m_uiSystem->setClipboardDelegate(&m_modules->m_clipboard);
|
m_uiSystem->setClipboardDelegate(&m_modules->m_clipboard);
|
||||||
|
|
||||||
// Setup the GUI cursor and redraw screen
|
// Setup the GUI cursor and redraw screen
|
||||||
ui::set_use_native_cursors(preferences().cursor.useNativeCursor());
|
ui::set_use_native_cursors(pref.cursor.useNativeCursor());
|
||||||
ui::set_mouse_cursor_scale(preferences().cursor.cursorScale());
|
ui::set_mouse_cursor_scale(pref.cursor.cursorScale());
|
||||||
ui::set_mouse_cursor(kArrowCursor);
|
ui::set_mouse_cursor(kArrowCursor);
|
||||||
|
|
||||||
auto manager = ui::Manager::getDefault();
|
auto manager = ui::Manager::getDefault();
|
||||||
@ -385,7 +392,7 @@ int App::initialize(const AppOptions& options)
|
|||||||
m_mod->modMainWindow(m_mainWindow.get());
|
m_mod->modMainWindow(m_mainWindow.get());
|
||||||
|
|
||||||
// Data recovery is enabled only in GUI mode
|
// Data recovery is enabled only in GUI mode
|
||||||
if (preferences().general.dataRecovery())
|
if (pref.general.dataRecovery())
|
||||||
m_modules->searchDataRecoverySessions();
|
m_modules->searchDataRecoverySessions();
|
||||||
|
|
||||||
// Default status of the main window.
|
// Default status of the main window.
|
||||||
|
@ -429,33 +429,20 @@ public:
|
|||||||
!nativeFileDialog()->isSelected());
|
!nativeFileDialog()->isSelected());
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef _WIN32 // Show Tablet section on Windows
|
#ifdef LAF_WINDOWS // Show Tablet section on Windows
|
||||||
{
|
{
|
||||||
os::TabletAPI tabletAPI = os::instance()->tabletAPI();
|
const os::TabletAPI tabletAPI = os::instance()->tabletAPI();
|
||||||
|
if (tabletAPI == os::TabletAPI::Wintab)
|
||||||
if (tabletAPI == os::TabletAPI::Wintab) {
|
|
||||||
tabletApiWintabSystem()->setSelected(true);
|
tabletApiWintabSystem()->setSelected(true);
|
||||||
loadWintabDriver()->setSelected(true);
|
else if (tabletAPI == os::TabletAPI::WintabPackets)
|
||||||
loadWintabDriver2()->setSelected(true);
|
|
||||||
}
|
|
||||||
else if (tabletAPI == os::TabletAPI::WintabPackets) {
|
|
||||||
tabletApiWintabDirect()->setSelected(true);
|
tabletApiWintabDirect()->setSelected(true);
|
||||||
loadWintabDriver()->setSelected(true);
|
else
|
||||||
loadWintabDriver2()->setSelected(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tabletApiWindowsPointer()->setSelected(true);
|
tabletApiWindowsPointer()->setSelected(true);
|
||||||
loadWintabDriver()->setSelected(false);
|
onTabletAPIChange();
|
||||||
loadWintabDriver2()->setSelected(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
tabletApiWindowsPointer()->Click.connect([this](){ onTabletAPIChange(); });
|
tabletApiWindowsPointer()->Click.connect([this](){ onTabletAPIChange(); });
|
||||||
tabletApiWintabSystem()->Click.connect([this](){ onTabletAPIChange(); });
|
tabletApiWintabSystem()->Click.connect([this](){ onTabletAPIChange(); });
|
||||||
tabletApiWintabDirect()->Click.connect([this](){ onTabletAPIChange(); });
|
tabletApiWintabDirect()->Click.connect([this](){ onTabletAPIChange(); });
|
||||||
loadWintabDriver()->Click.connect(
|
|
||||||
[this](){ onLoadWintabChange(loadWintabDriver()->isSelected()); });
|
|
||||||
loadWintabDriver2()->Click.connect(
|
|
||||||
[this](){ onLoadWintabChange(loadWintabDriver2()->isSelected()); });
|
|
||||||
}
|
}
|
||||||
#else // For macOS and Linux
|
#else // For macOS and Linux
|
||||||
{
|
{
|
||||||
@ -467,8 +454,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sectionTablet()->setVisible(false);
|
sectionTablet()->setVisible(false);
|
||||||
loadWintabDriverBox()->setVisible(false);
|
|
||||||
loadWintabDriverBox()->setVisible(false);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -832,7 +817,7 @@ public:
|
|||||||
m_pref.experimental.nonactiveLayersOpacity(nonactiveLayersOpacity()->getValue());
|
m_pref.experimental.nonactiveLayersOpacity(nonactiveLayersOpacity()->getValue());
|
||||||
m_pref.quantization.rgbmapAlgorithm(m_rgbmapAlgorithmSelector.algorithm());
|
m_pref.quantization.rgbmapAlgorithm(m_rgbmapAlgorithmSelector.algorithm());
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef LAF_WINDOWS
|
||||||
{
|
{
|
||||||
os::TabletAPI tabletAPI = os::TabletAPI::Default;
|
os::TabletAPI tabletAPI = os::TabletAPI::Default;
|
||||||
std::string tabletStr;
|
std::string tabletStr;
|
||||||
@ -860,7 +845,10 @@ public:
|
|||||||
->setInterpretOneFingerGestureAsMouseMovement(
|
->setInterpretOneFingerGestureAsMouseMovement(
|
||||||
oneFingerAsMouseMovement()->isSelected());
|
oneFingerAsMouseMovement()->isSelected());
|
||||||
|
|
||||||
os::instance()->setTabletAPI(tabletAPI);
|
os::TabletOptions options;
|
||||||
|
options.api = tabletAPI;
|
||||||
|
options.setCursorFix = m_pref.tablet.setCursorFix();
|
||||||
|
os::instance()->setTabletOptions(options);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1782,28 +1770,13 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef LAF_WINDOWS
|
||||||
void onTabletAPIChange() {
|
void onTabletAPIChange() {
|
||||||
if (tabletApiWindowsPointer()->isSelected()) {
|
const bool pointerApi = tabletApiWindowsPointer()->isSelected();
|
||||||
loadWintabDriver()->setSelected(false);
|
windowsPointerOptions()->setVisible(pointerApi);
|
||||||
loadWintabDriver2()->setSelected(false);
|
sectionTablet()->layout();
|
||||||
}
|
|
||||||
else if (tabletApiWintabSystem()->isSelected() ||
|
|
||||||
tabletApiWintabDirect()->isSelected()) {
|
|
||||||
loadWintabDriver()->setSelected(true);
|
|
||||||
loadWintabDriver2()->setSelected(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void onLoadWintabChange(bool state) {
|
#endif // LAF_WINDOWS
|
||||||
loadWintabDriver()->setSelected(state);
|
|
||||||
loadWintabDriver2()->setSelected(state);
|
|
||||||
if (state)
|
|
||||||
tabletApiWintabSystem()->setSelected(true);
|
|
||||||
else
|
|
||||||
tabletApiWindowsPointer()->setSelected(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
Context* m_context;
|
Context* m_context;
|
||||||
Preferences& m_pref;
|
Preferences& m_pref;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user