From 38bea01dab8f4dedd5fce9f8b9e82cebbf663189 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 22 Jan 2022 15:45:00 +0100 Subject: [PATCH 1/7] device: Do not enumerate keyboard/mouse devices on macOS by default This causes an annoying "this app would like to receive keystrokes from any application" alert to be shown Enable iokit-scan-mouse-devices or iokit-scan-keyboard-devices to restore the old behavior --- panda/src/device/ioKitInputDeviceManager.cxx | 27 +++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/panda/src/device/ioKitInputDeviceManager.cxx b/panda/src/device/ioKitInputDeviceManager.cxx index 3f1c807469..aa8d67301c 100644 --- a/panda/src/device/ioKitInputDeviceManager.cxx +++ b/panda/src/device/ioKitInputDeviceManager.cxx @@ -16,6 +16,18 @@ #if defined(__APPLE__) && !defined(CPPPARSER) +static ConfigVariableBool iokit_scan_mouse_devices +("iokit-scan-mouse-devices", false, + PRC_DESC("Set this to true to enable capturing raw mouse data via IOKit on " + "macOS. This is disabled by default because newer macOS versions " + "will prompt the user explicitly for permissions when this is on.")); + +static ConfigVariableBool iokit_scan_keyboard_devices +("iokit-scan-keyboard-devices", false, + PRC_DESC("Set this to true to enable capturing raw keyboard data via IOKit on " + "macOS. This is disabled by default because newer macOS versions " + "will prompt the user explicitly for permissions when this is on.")); + /** * Initializes the input device manager by scanning which devices are currently * connected and setting up any platform-dependent structures necessary for @@ -34,15 +46,22 @@ IOKitInputDeviceManager() { int page = kHIDPage_GenericDesktop; int usages[] = {kHIDUsage_GD_GamePad, kHIDUsage_GD_Joystick, - kHIDUsage_GD_Mouse, - kHIDUsage_GD_Keyboard, - kHIDUsage_GD_MultiAxisController, 0}; - int *usage = usages; + kHIDUsage_GD_MultiAxisController, + 0, 0, 0}; + + int num_usages = 3; + if (iokit_scan_mouse_devices) { + usages[num_usages++] = kHIDUsage_GD_Mouse; + } + if (iokit_scan_keyboard_devices) { + usages[num_usages++] = kHIDUsage_GD_Keyboard; + } // This giant mess is necessary to create an array of match dictionaries // that will match the devices we're interested in. CFMutableArrayRef match = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); nassertv(match); + int *usage = usages; while (*usage) { CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFNumberRef page_ref = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); From 692221cacb284b40cf3fe4944089eada69207611 Mon Sep 17 00:00:00 2001 From: rdb Date: Sat, 22 Jan 2022 15:56:53 +0100 Subject: [PATCH 2/7] cocoadisplay: Invert direction of horizontal scroll Now behaves consistent with other applications (tested with Logitech MX Master 3 for Mac on macOS 10.13 in unnatural scrolling configuration). Set `cocoa-invert-wheel-x true` to revert to old behaviour. --- panda/src/cocoadisplay/cocoaGraphicsWindow.mm | 15 ++++++++++----- panda/src/cocoadisplay/config_cocoadisplay.h | 2 ++ panda/src/cocoadisplay/config_cocoadisplay.mm | 5 +++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 87a3c96777..0b973a0317 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -2021,8 +2021,10 @@ handle_mouse_moved_event(bool in_window, double x, double y, bool absolute) { */ void CocoaGraphicsWindow:: handle_wheel_event(double x, double y) { - cocoadisplay_cat.spam() - << "Wheel delta " << x << ", " << y << "\n"; + if (cocoadisplay_cat.is_spam()) { + cocoadisplay_cat.spam() + << "Wheel delta " << x << ", " << y << "\n"; + } if (y > 0.0) { _input->button_down(MouseButton::wheel_up()); @@ -2032,11 +2034,14 @@ handle_wheel_event(double x, double y) { _input->button_up(MouseButton::wheel_down()); } - // TODO: check if this is correct, I don't own a MacBook - if (x > 0.0) { + if (x != 0 && cocoa_invert_wheel_x) { + x = -x; + } + + if (x < 0.0) { _input->button_down(MouseButton::wheel_right()); _input->button_up(MouseButton::wheel_right()); - } else if (x < 0.0) { + } else if (x > 0.0) { _input->button_down(MouseButton::wheel_left()); _input->button_up(MouseButton::wheel_left()); } diff --git a/panda/src/cocoadisplay/config_cocoadisplay.h b/panda/src/cocoadisplay/config_cocoadisplay.h index 43a0e057c3..43051a67c5 100644 --- a/panda/src/cocoadisplay/config_cocoadisplay.h +++ b/panda/src/cocoadisplay/config_cocoadisplay.h @@ -20,6 +20,8 @@ NotifyCategoryDecl(cocoadisplay, EXPCL_PANDA_COCOADISPLAY, EXPTP_PANDA_COCOADISPLAY); +extern ConfigVariableBool cocoa_invert_wheel_x; + extern EXPCL_PANDA_COCOADISPLAY void init_libcocoadisplay(); #endif diff --git a/panda/src/cocoadisplay/config_cocoadisplay.mm b/panda/src/cocoadisplay/config_cocoadisplay.mm index 96662d6c9c..a79144769b 100644 --- a/panda/src/cocoadisplay/config_cocoadisplay.mm +++ b/panda/src/cocoadisplay/config_cocoadisplay.mm @@ -31,6 +31,11 @@ ConfigureFn(config_cocoadisplay) { init_libcocoadisplay(); } +ConfigVariableBool cocoa_invert_wheel_x +("cocoa-invert-wheel-x", false, + PRC_DESC("Set this to true to swap the wheel_left and wheel_right mouse " + "button events, to restore to the pre-1.10.12 behavior.")); + /** * Initializes the library. This must be called at least once before any of * the functions or classes in this library can be used. Normally it will be From a12359275f5bfcfa9be561674c4c4f58a6eb8052 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 6 Feb 2022 14:45:56 +0100 Subject: [PATCH 3/7] makepanda: Support building with OpenSSL 1.1.1 on Windows --- makepanda/makepanda.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 71aa749a23..42c35436f8 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -771,9 +771,14 @@ if (COMPILER == "MSVC"): if os.path.isfile(GetThirdpartyDir() + "openssl/lib/libpandassl.lib"): LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/libpandassl.lib") LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/libpandaeay.lib") - else: + elif os.path.isfile(GetThirdpartyDir() + "openssl/lib/ssleay32.lib"): LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/libeay32.lib") LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/ssleay32.lib") + else: + LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/libssl.lib") + LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/libcrypto.lib") + LibName("OPENSSL", "crypt32.lib") + LibName("OPENSSL", "ws2_32.lib") if (PkgSkip("PNG")==0): if os.path.isfile(GetThirdpartyDir() + "png/lib/libpng16_static.lib"): LibName("PNG", GetThirdpartyDir() + "png/lib/libpng16_static.lib") From bc6502a8fee424a41ef6c8199c602445729fea35 Mon Sep 17 00:00:00 2001 From: Disyer Date: Sat, 5 Feb 2022 23:16:59 +0200 Subject: [PATCH 4/7] makepanda: Record cache timestamps as integers rather than floats We don't need the extra precision, in fact it is detrimental to restoring build caches in a cross-platform way. This commit will invalidate all current build caches. Cherry-picked from 2a904f398592ce7effedc4f12720be0cef9b6cc9 (see #1260) --- makepanda/makepandacore.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index 1ecf349fb1..e650ef019f 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -714,8 +714,10 @@ TIMESTAMPCACHE = {} def GetTimestamp(path): if path in TIMESTAMPCACHE: return TIMESTAMPCACHE[path] - try: date = os.path.getmtime(path) - except: date = 0 + try: + date = int(os.path.getmtime(path)) + except: + date = 0 TIMESTAMPCACHE[path] = date return date @@ -866,7 +868,7 @@ def JavaGetImports(path): ## ######################################################################## -DCACHE_VERSION = 2 +DCACHE_VERSION = 3 DCACHE_BACKED_UP = False def SaveDependencyCache(): From be2e07637f0f31a3957bdc215e4ad23eb6de79a5 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 1 Feb 2022 13:35:32 +0100 Subject: [PATCH 5/7] gtk-stats: Fix mouse motion detected outside strip chart graph area Cherry-picked from 3a38543f65670b2d754838c5b08a556df1485a01 --- .../src/gtk-stats/gtkStatsStripChart.cxx | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/pandatool/src/gtk-stats/gtkStatsStripChart.cxx b/pandatool/src/gtk-stats/gtkStatsStripChart.cxx index 117ef96576..1015c7989a 100644 --- a/pandatool/src/gtk-stats/gtkStatsStripChart.cxx +++ b/pandatool/src/gtk-stats/gtkStatsStripChart.cxx @@ -402,20 +402,23 @@ set_drag_mode(GtkStatsGraph::DragMode drag_mode) { gboolean GtkStatsStripChart:: handle_button_press(GtkWidget *widget, int graph_x, int graph_y, bool double_click) { - if (double_click) { - // Double-clicking on a color bar in the graph is the same as double- - // clicking on the corresponding label. - clicked_label(get_collector_under_pixel(graph_x, graph_y)); - return TRUE; + if (graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { + if (double_click) { + // Double-clicking on a color bar in the graph is the same as double- + // clicking on the corresponding label. + clicked_label(get_collector_under_pixel(graph_x, graph_y)); + return TRUE; + } + + if (_potential_drag_mode == DM_none) { + set_drag_mode(DM_scale); + _drag_scale_start = pixel_to_height(graph_y); + // SetCapture(_graph_window); + return TRUE; + } } - if (_potential_drag_mode == DM_none) { - set_drag_mode(DM_scale); - _drag_scale_start = pixel_to_height(graph_y); - // SetCapture(_graph_window); - return TRUE; - - } else if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) { + if (_potential_drag_mode == DM_guide_bar && _drag_guide_bar >= 0) { set_drag_mode(DM_guide_bar); _drag_start_y = graph_y; // SetCapture(_graph_window); @@ -455,7 +458,8 @@ handle_button_release(GtkWidget *widget, int graph_x, int graph_y) { */ gboolean GtkStatsStripChart:: handle_motion(GtkWidget *widget, int graph_x, int graph_y) { - if (_drag_mode == DM_none && _potential_drag_mode == DM_none) { + if (_drag_mode == DM_none && _potential_drag_mode == DM_none && + graph_x >= 0 && graph_y >= 0 && graph_x < get_xsize() && graph_y < get_ysize()) { // When the mouse is over a color bar, highlight it. _label_stack.highlight_label(get_collector_under_pixel(graph_x, graph_y)); From a37dfa727e25b81b5f0de962677b2c1ee600f16b Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 6 Feb 2022 15:24:33 +0100 Subject: [PATCH 6/7] makepanda: Support building with mimalloc on Windows, experimentally Partial backport of 07545bc9e318d1799ceabe8838d04d7ad9297a45 for Windows, requires building with `--override USE_MEMORY_MIMALLOC=1 --override USE_DELETED_CHAIN=UNDEF` for optimum effect --- dtool/src/dtoolbase/dtoolbase.h | 6 +++++- dtool/src/dtoolbase/memoryHook.cxx | 12 ++++++++++++ makepanda/makepanda.py | 8 ++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h index 66142427cc..d89caf2a92 100644 --- a/dtool/src/dtoolbase/dtoolbase.h +++ b/dtool/src/dtoolbase/dtoolbase.h @@ -387,6 +387,10 @@ typedef struct _object PyObject; // This specialized malloc implementation can perform the required alignment. #undef MEMORY_HOOK_DO_ALIGN +#elif defined(USE_MEMORY_MIMALLOC) +// This one does, too. +#undef MEMORY_HOOK_DO_ALIGN + #elif defined(USE_MEMORY_PTMALLOC2) // But not this one. For some reason it crashes when we try to build it with // alignment 16. So if we're using ptmalloc2, we need to enforce alignment @@ -438,7 +442,7 @@ typedef struct _object PyObject; #endif /* Determine our memory-allocation requirements. */ -#if defined(USE_MEMORY_PTMALLOC2) || defined(USE_MEMORY_DLMALLOC) || defined(DO_MEMORY_USAGE) || defined(MEMORY_HOOK_DO_ALIGN) +#if defined(USE_MEMORY_MIMALLOC) || defined(USE_MEMORY_PTMALLOC2) || defined(USE_MEMORY_DLMALLOC) || defined(DO_MEMORY_USAGE) || defined(MEMORY_HOOK_DO_ALIGN) /* In this case we have some custom memory management requirements. */ #else /* Otherwise, if we have no custom memory management needs at all, we diff --git a/dtool/src/dtoolbase/memoryHook.cxx b/dtool/src/dtoolbase/memoryHook.cxx index 24d5f11a11..7f5872d273 100644 --- a/dtool/src/dtoolbase/memoryHook.cxx +++ b/dtool/src/dtoolbase/memoryHook.cxx @@ -51,6 +51,18 @@ static_assert((MEMORY_HOOK_ALIGNMENT & (MEMORY_HOOK_ALIGNMENT - 1)) == 0, #if defined(CPPPARSER) +#elif defined(USE_MEMORY_MIMALLOC) + +// mimalloc is a modern memory manager by Microsoft that is very fast as well +// as thread-safe. + +#include "mimalloc.h" + +#define call_malloc mi_malloc +#define call_realloc mi_realloc +#define call_free mi_free +#undef MEMORY_HOOK_MALLOC_LOCK + #elif defined(USE_MEMORY_DLMALLOC) // Memory manager: DLMALLOC This is Doug Lea's memory manager. It is very diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 42c35436f8..5d22f69026 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -103,6 +103,7 @@ PkgListSet(["PYTHON", "DIRECT", # Python support "PANDAPARTICLESYSTEM", # Built in particle system "CONTRIB", # Experimental "SSE2", "NEON", # Compiler features + "MIMALLOC", # Memory allocators ]) CheckPandaSourceTree() @@ -767,6 +768,7 @@ if (COMPILER == "MSVC"): if (PkgSkip("DIRECTCAM")==0): LibName("DIRECTCAM", "quartz.lib") if (PkgSkip("DIRECTCAM")==0): LibName("DIRECTCAM", "odbc32.lib") if (PkgSkip("DIRECTCAM")==0): LibName("DIRECTCAM", "odbccp32.lib") + if (PkgSkip("MIMALLOC")==0): LibName("MIMALLOC", GetThirdpartyDir() + "mimalloc/lib/mimalloc-static.lib") if (PkgSkip("OPENSSL")==0): if os.path.isfile(GetThirdpartyDir() + "openssl/lib/libpandassl.lib"): LibName("OPENSSL", GetThirdpartyDir() + "openssl/lib/libpandassl.lib") @@ -949,6 +951,8 @@ if (COMPILER == "MSVC"): LibName("BULLET", GetThirdpartyDir() + "bullet/lib/BulletSoftBody" + suffix) if (COMPILER=="GCC"): + PkgDisable("MIMALLOC") # no discernable benefit over glibc + if GetTarget() != "darwin": PkgDisable("CARBON") PkgDisable("COCOA") @@ -3766,7 +3770,7 @@ if GetTarget() == 'windows': # DIRECTORY: dtool/src/dtoolbase/ # -OPTS=['DIR:dtool/src/dtoolbase', 'BUILDING:DTOOL'] +OPTS=['DIR:dtool/src/dtoolbase', 'BUILDING:DTOOL', 'MIMALLOC'] TargetAdd('p3dtoolbase_composite1.obj', opts=OPTS, input='p3dtoolbase_composite1.cxx') TargetAdd('p3dtoolbase_composite2.obj', opts=OPTS, input='p3dtoolbase_composite2.cxx') TargetAdd('p3dtoolbase_lookup3.obj', opts=OPTS, input='lookup3.c') @@ -3797,7 +3801,7 @@ TargetAdd('libp3dtool.dll', input='p3dtoolbase_composite1.obj') TargetAdd('libp3dtool.dll', input='p3dtoolbase_composite2.obj') TargetAdd('libp3dtool.dll', input='p3dtoolbase_indent.obj') TargetAdd('libp3dtool.dll', input='p3dtoolbase_lookup3.obj') -TargetAdd('libp3dtool.dll', opts=['ADVAPI','WINSHELL','WINKERNEL']) +TargetAdd('libp3dtool.dll', opts=['ADVAPI','WINSHELL','WINKERNEL','MIMALLOC']) # # DIRECTORY: dtool/src/cppparser/ From 287b0d5a74530762262e78f070a5d34b6c42c216 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 6 Feb 2022 15:26:41 +0100 Subject: [PATCH 7/7] mathutil: Add proper `__repr__` for LPlane class Fixes #1248 --- panda/src/mathutil/plane_src.cxx | 14 ++++++++++++++ panda/src/mathutil/plane_src.h | 1 + 2 files changed, 15 insertions(+) diff --git a/panda/src/mathutil/plane_src.cxx b/panda/src/mathutil/plane_src.cxx index 7ba18701c6..4463d57756 100644 --- a/panda/src/mathutil/plane_src.cxx +++ b/panda/src/mathutil/plane_src.cxx @@ -158,3 +158,17 @@ void FLOATNAME(LPlane):: write(std::ostream &out, int indent_level) const { indent(out, indent_level) << *this << "\n"; } + +/** + * Returns a string representation of this LPlane. + */ +std::string FLOATNAME(LPlane):: +__repr__() const { + std::ostringstream out; + out << "LPlane" << FLOATTOKEN << "(" + << MAYBE_ZERO(_v(0)) << ", " + << MAYBE_ZERO(_v(1)) << ", " + << MAYBE_ZERO(_v(2)) << ", " + << MAYBE_ZERO(_v(3)) << ")"; + return out.str(); +} diff --git a/panda/src/mathutil/plane_src.h b/panda/src/mathutil/plane_src.h index c1dffc4d5d..c1d7ef0252 100644 --- a/panda/src/mathutil/plane_src.h +++ b/panda/src/mathutil/plane_src.h @@ -61,6 +61,7 @@ PUBLISHED: void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; + std::string __repr__() const; }; INLINE_MATHUTIL std::ostream &