From 3c35c535d59ce0c31cd39ca33e22a17ba24d274d Mon Sep 17 00:00:00 2001 From: Mino260806 Date: Wed, 31 Jul 2024 10:17:32 +0100 Subject: [PATCH 1/2] fix horizontal scrolling in linux --- .../main/java/jadx/gui/ui/JadxEventQueue.java | 44 +++++++++++++++++++ .../src/main/java/jadx/gui/ui/MainWindow.java | 2 + .../src/main/java/jadx/gui/utils/UiUtils.java | 7 +++ 3 files changed, 53 insertions(+) create mode 100644 jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java diff --git a/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java b/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java new file mode 100644 index 00000000000..282447f89ff --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java @@ -0,0 +1,44 @@ +package jadx.gui.ui; + +import java.awt.AWTEvent; +import java.awt.EventQueue; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +import jadx.gui.utils.UiUtils; + +public class JadxEventQueue extends EventQueue { + @Override + protected void dispatchEvent(AWTEvent event) { + event = mapEvent(event); + super.dispatchEvent(event); + } + + private static AWTEvent mapEvent(AWTEvent e) { + if (UiUtils.isXToolkit() && e instanceof MouseEvent && ((MouseEvent) e).getButton() > 3) { + return mapXWindowMouseEvent((MouseEvent) e); + } else { + return e; + } + } + + private static AWTEvent mapXWindowMouseEvent(MouseEvent src) { + if (src.getButton() < 6) { + // buttons 4-5 come from touchpad, they must be converted to horizontal scrolling events + @SuppressWarnings("deprecation") + int modifiers = src.getModifiers() | InputEvent.SHIFT_DOWN_MASK; + // noinspection MagicConstant + return new MouseWheelEvent(src.getComponent(), MouseEvent.MOUSE_WHEEL, src.getWhen(), modifiers, + src.getX(), src.getY(), 0, false, MouseWheelEvent.WHEEL_UNIT_SCROLL, + src.getClickCount(), src.getButton() == 4 ? -1 : 1); + } else { + // Here we "shift" events with buttons `6` and `7` to similar events with buttons 4 and 5 + @SuppressWarnings("deprecation") + int modifiers = src.getModifiers() | (1 << (8 + src.getButton())); + // noinspection MagicConstant + return new MouseEvent(src.getComponent(), src.getID(), src.getWhen(), modifiers, + src.getX(), src.getY(), 1, src.isPopupTrigger(), src.getButton() - 2); + } + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index ae01e65e2a1..fa82621489e 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -8,6 +8,7 @@ import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; @@ -250,6 +251,7 @@ public MainWindow(JadxSettings settings) { this.cacheManager = new CacheManager(settings); this.shortcutsController = new ShortcutsController(settings); + Toolkit.getDefaultToolkit().getSystemEventQueue().push(new JadxEventQueue()); resetCache(); FontUtils.registerBundledFonts(); setEditorTheme(settings.getEditorThemePath()); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java b/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java index f677e76792d..67a417d87fe 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java @@ -30,6 +30,7 @@ import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.TestOnly; +import org.jetbrains.kotlin.com.intellij.openapi.util.SystemInfoRt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -394,6 +395,12 @@ public static void notUiThreadGuard() { } } + public static boolean isXToolkit() { + return SystemInfoRt.isUnix + && !SystemInfoRt.isMac + && "sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName()); + } + @TestOnly public static void debugTimer(int periodInSeconds, Runnable action) { if (!LOG.isDebugEnabled()) { From 7f348ef2082a596badcfde3a69eb03ddcf25f3f8 Mon Sep 17 00:00:00 2001 From: Skylot <118523+skylot@users.noreply.github.com> Date: Wed, 31 Jul 2024 16:48:04 +0100 Subject: [PATCH 2/2] improve code --- .../main/java/jadx/gui/ui/JadxEventQueue.java | 32 ++++++++++++------- .../src/main/java/jadx/gui/ui/MainWindow.java | 3 +- .../main/java/jadx/gui/utils/SystemInfo.java | 1 + .../src/main/java/jadx/gui/utils/UiUtils.java | 5 ++- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java b/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java index 282447f89ff..c07f08a3b2a 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/JadxEventQueue.java @@ -2,6 +2,7 @@ import java.awt.AWTEvent; import java.awt.EventQueue; +import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; @@ -9,34 +10,43 @@ import jadx.gui.utils.UiUtils; public class JadxEventQueue extends EventQueue { + + private static final boolean IS_X_TOOLKIT = UiUtils.isXToolkit(); + + public static void register() { + if (IS_X_TOOLKIT) { + Toolkit.getDefaultToolkit().getSystemEventQueue().push(new JadxEventQueue()); + } + } + + private JadxEventQueue() { + } + @Override protected void dispatchEvent(AWTEvent event) { - event = mapEvent(event); - super.dispatchEvent(event); + AWTEvent mappedEvent = mapEvent(event); + super.dispatchEvent(mappedEvent); } - private static AWTEvent mapEvent(AWTEvent e) { - if (UiUtils.isXToolkit() && e instanceof MouseEvent && ((MouseEvent) e).getButton() > 3) { - return mapXWindowMouseEvent((MouseEvent) e); - } else { - return e; + private static AWTEvent mapEvent(AWTEvent event) { + if (IS_X_TOOLKIT && event instanceof MouseEvent && ((MouseEvent) event).getButton() > 3) { + return mapXWindowMouseEvent((MouseEvent) event); } + return event; } + @SuppressWarnings({ "deprecation", "MagicConstant" }) private static AWTEvent mapXWindowMouseEvent(MouseEvent src) { if (src.getButton() < 6) { // buttons 4-5 come from touchpad, they must be converted to horizontal scrolling events - @SuppressWarnings("deprecation") int modifiers = src.getModifiers() | InputEvent.SHIFT_DOWN_MASK; - // noinspection MagicConstant return new MouseWheelEvent(src.getComponent(), MouseEvent.MOUSE_WHEEL, src.getWhen(), modifiers, src.getX(), src.getY(), 0, false, MouseWheelEvent.WHEEL_UNIT_SCROLL, src.getClickCount(), src.getButton() == 4 ? -1 : 1); } else { // Here we "shift" events with buttons `6` and `7` to similar events with buttons 4 and 5 - @SuppressWarnings("deprecation") + // See `java.awt.InputEvent#BUTTON_DOWN_MASK`, 1<<14 is the 4th physical button, 1<<15 is the 5th. int modifiers = src.getModifiers() | (1 << (8 + src.getButton())); - // noinspection MagicConstant return new MouseEvent(src.getComponent(), src.getID(), src.getWhen(), modifiers, src.getX(), src.getY(), 1, src.isPopupTrigger(), src.getButton() - 2); } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index fa82621489e..1dfb87ac6a7 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -8,7 +8,6 @@ import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; -import java.awt.Toolkit; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; @@ -251,7 +250,7 @@ public MainWindow(JadxSettings settings) { this.cacheManager = new CacheManager(settings); this.shortcutsController = new ShortcutsController(settings); - Toolkit.getDefaultToolkit().getSystemEventQueue().push(new JadxEventQueue()); + JadxEventQueue.register(); resetCache(); FontUtils.registerBundledFonts(); setEditorTheme(settings.getEditorThemePath()); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java b/jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java index e7c24e43f8a..f9dae09be84 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java @@ -17,6 +17,7 @@ public class SystemInfo { public static final boolean IS_WINDOWS = LOWER_OS_NAME.startsWith("windows"); public static final boolean IS_MAC = LOWER_OS_NAME.startsWith("mac"); public static final boolean IS_LINUX = LOWER_OS_NAME.startsWith("linux"); + public static final boolean IS_UNIX = !IS_WINDOWS; private SystemInfo() { } diff --git a/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java b/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java index 67a417d87fe..398c2211a84 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/UiUtils.java @@ -30,7 +30,6 @@ import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.TestOnly; -import org.jetbrains.kotlin.com.intellij.openapi.util.SystemInfoRt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -396,8 +395,8 @@ public static void notUiThreadGuard() { } public static boolean isXToolkit() { - return SystemInfoRt.isUnix - && !SystemInfoRt.isMac + return SystemInfo.IS_UNIX + && !SystemInfo.IS_MAC && "sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName()); }