autoclicker reimplemented
This commit is contained in:
parent
37f49c5f33
commit
0998ba3762
@ -1,12 +1,13 @@
|
|||||||
#Pokémon GO Automatizace - Nastavení
|
#Pokémon GO Automatizace - Nastavení
|
||||||
#Sat Dec 20 18:52:36 CET 2025
|
#Fri Jan 23 16:03:46 CET 2026
|
||||||
autoklik.count=1
|
autoklik.count=1000
|
||||||
window.width=807
|
window.width=807
|
||||||
transfer.delay=0
|
transfer.delay=0
|
||||||
|
autoklik.x=2123
|
||||||
window.height=743
|
window.height=743
|
||||||
autoklik.x=2093
|
autoklik.downArrow=true
|
||||||
autoklik.y=670
|
autoklik.y=1129
|
||||||
|
autoklik.interval=150
|
||||||
transfer.count=6
|
transfer.count=6
|
||||||
window.x=1143
|
window.x=887
|
||||||
autoklik.interval=100
|
window.y=505
|
||||||
window.y=595
|
|
||||||
|
|||||||
@ -17,9 +17,39 @@ public class GlobalHotkey extends JLabel {
|
|||||||
public GlobalHotkey(Runnable onHotkey) {
|
public GlobalHotkey(Runnable onHotkey) {
|
||||||
this.globalKeyListener = new GlobalKeyListener(onHotkey);
|
this.globalKeyListener = new GlobalKeyListener(onHotkey);
|
||||||
|
|
||||||
// Registrace globálního key listeneru
|
// Registrace globálního key listeneru pro případy, kdy má aplikace fokus
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
.addKeyEventDispatcher(globalKeyListener);
|
.addKeyEventDispatcher(globalKeyListener);
|
||||||
|
|
||||||
|
// Spustit nativní polling pro globální STOP hotkey na Linuxu (funguje i bez fokusu)
|
||||||
|
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||||
|
Thread pollingThread = new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(150);
|
||||||
|
// Kontrola CTRL+ALT+X globálně
|
||||||
|
// XK_Control_L/R: 0xFFE3/4, XK_Alt_L/R: 0xFFE9/A, XK_x: 0x78, XK_X: 0x58
|
||||||
|
boolean ctrl = WindowFinder.isKeyPressedGlobally(0xFFE3) || WindowFinder.isKeyPressedGlobally(0xFFE4);
|
||||||
|
boolean alt = WindowFinder.isKeyPressedGlobally(0xFFE9) || WindowFinder.isKeyPressedGlobally(0xFFEA);
|
||||||
|
boolean xPressed = WindowFinder.isKeyPressedGlobally(0x78) || WindowFinder.isKeyPressedGlobally(0x58);
|
||||||
|
|
||||||
|
if (ctrl && alt && xPressed) {
|
||||||
|
if (onHotkey != null) {
|
||||||
|
System.out.println("🔌 Globální NATIVNÍ hotkey detekován: CTRL+ALT+X");
|
||||||
|
onHotkey.run();
|
||||||
|
Thread.sleep(1000); // Prevence vícenásobného spuštění
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignorovat chyby v pollingu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "GlobalHotkeyPolling");
|
||||||
|
pollingThread.setDaemon(true);
|
||||||
|
pollingThread.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GlobalHotkey create(Runnable onHotkey) {
|
public static GlobalHotkey create(Runnable onHotkey) {
|
||||||
@ -29,6 +59,23 @@ public class GlobalHotkey extends JLabel {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isKeyPressed(int keyCode) {
|
||||||
|
// Na Linuxu pro šipky používáme výhradně nativní globální detekci.
|
||||||
|
// Standardní KeyEventDispatcher se může "zaseknout", pokud okno ztratí fokus během stisku.
|
||||||
|
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||||
|
if (keyCode == KeyEvent.VK_DOWN) {
|
||||||
|
try {
|
||||||
|
return WindowFinder.isKeyPressedGlobally(0xFF54); // XK_Down
|
||||||
|
} catch (Exception e) {}
|
||||||
|
} else if (keyCode == KeyEvent.VK_UP) {
|
||||||
|
try {
|
||||||
|
return WindowFinder.isKeyPressedGlobally(0xFF52); // XK_Up
|
||||||
|
} catch (Exception e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return globalKeyListener.isKeyPressed(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interní třída pro globální naslouchání na klávesnici
|
* Interní třída pro globální naslouchání na klávesnici
|
||||||
*/
|
*/
|
||||||
@ -40,6 +87,10 @@ public class GlobalHotkey extends JLabel {
|
|||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isKeyPressed(int keyCode) {
|
||||||
|
return pressedKeys.contains(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchKeyEvent(KeyEvent e) {
|
public boolean dispatchKeyEvent(KeyEvent e) {
|
||||||
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
||||||
|
|||||||
@ -363,92 +363,24 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
centerPanel.add(createFieldPanel("Počet:", countComboBox));
|
centerPanel.add(createFieldPanel("Počet:", countComboBox));
|
||||||
centerPanel.add(createFieldPanel("Čekání (s):", delaySpinner));
|
centerPanel.add(createFieldPanel("Čekání (s):", delaySpinner));
|
||||||
} else if (title.contains("AUTOKLIK")) {
|
} else if (title.contains("AUTOKLIK")) {
|
||||||
JSpinner xSpinner = new JSpinner(new SpinnerNumberModel(
|
|
||||||
Integer.parseInt(settings.getProperty("autoklik.x", "960")),
|
|
||||||
0, 9999, 1
|
|
||||||
));
|
|
||||||
xSpinner.setPreferredSize(new Dimension(70, 26));
|
|
||||||
card.putClientProperty("xSpinner", xSpinner);
|
|
||||||
|
|
||||||
JSpinner ySpinner = new JSpinner(new SpinnerNumberModel(
|
|
||||||
Integer.parseInt(settings.getProperty("autoklik.y", "540")),
|
|
||||||
0, 9999, 1
|
|
||||||
));
|
|
||||||
ySpinner.setPreferredSize(new Dimension(70, 26));
|
|
||||||
card.putClientProperty("ySpinner", ySpinner);
|
|
||||||
|
|
||||||
JSpinner intervalSpinner = new JSpinner(new SpinnerNumberModel(
|
JSpinner intervalSpinner = new JSpinner(new SpinnerNumberModel(
|
||||||
Integer.parseInt(settings.getProperty("autoklik.interval", "100")),
|
Integer.parseInt(settings.getProperty("autoklik.interval", "100")),
|
||||||
10, 10000, 10
|
10, 10000, 10
|
||||||
));
|
));
|
||||||
intervalSpinner.setPreferredSize(new Dimension(70, 26));
|
intervalSpinner.setPreferredSize(new Dimension(80, 26));
|
||||||
card.putClientProperty("intervalSpinner", intervalSpinner);
|
card.putClientProperty("intervalSpinner", intervalSpinner);
|
||||||
|
|
||||||
JSpinner clickCountSpinner = new JSpinner(new SpinnerNumberModel(
|
|
||||||
Integer.parseInt(settings.getProperty("autoklik.count", "10")),
|
|
||||||
1, 10000, 1
|
|
||||||
));
|
|
||||||
clickCountSpinner.setPreferredSize(new Dimension(70, 26));
|
|
||||||
card.putClientProperty("clickCountSpinner", clickCountSpinner);
|
|
||||||
|
|
||||||
centerPanel.add(createFieldPanel("X:", xSpinner));
|
|
||||||
centerPanel.add(createFieldPanel("Y:", ySpinner));
|
|
||||||
centerPanel.add(createFieldPanel("Interval (ms):", intervalSpinner));
|
centerPanel.add(createFieldPanel("Interval (ms):", intervalSpinner));
|
||||||
centerPanel.add(createFieldPanel("Počet kliknutí:", clickCountSpinner));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pravý panel - START a Nastavit (pro AUTOKLIK) tlačítka
|
// Pravý panel - START tlačítko (a u Autokliku i STOP v rámci tlačítka)
|
||||||
JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
|
JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
|
||||||
rightPanel.setBackground(CARD_BACKGROUND);
|
rightPanel.setBackground(CARD_BACKGROUND);
|
||||||
rightPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
|
rightPanel.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
|
||||||
|
|
||||||
// Tlačítko Nastavit pro AUTOKLIK
|
// Tlačítko START / VYPNOUT
|
||||||
if (title.contains("AUTOKLIK")) {
|
|
||||||
JSpinner xSpinner = (JSpinner) card.getClientProperty("xSpinner");
|
|
||||||
JSpinner ySpinner = (JSpinner) card.getClientProperty("ySpinner");
|
|
||||||
|
|
||||||
JButton settingsBtn = new JButton("⚙ Nastavit");
|
|
||||||
settingsBtn.setPreferredSize(new Dimension(100, 32));
|
|
||||||
styleButton(settingsBtn, ACCENT_BLUE, Color.WHITE, SMALL_FONT);
|
|
||||||
settingsBtn.addActionListener(new ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
PositionPicker picker = new PositionPicker(null);
|
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
picker.setVisible(true);
|
|
||||||
|
|
||||||
while (picker.isVisible()) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(50);
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (picker.isPositionSelected()) {
|
|
||||||
Point pos = picker.getSelectedPosition();
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
xSpinner.setValue(pos.x);
|
|
||||||
ySpinner.setValue(pos.y);
|
|
||||||
logArea.append("✅ Pozice nastavena: (" + pos.x + ", " + pos.y + ")\n");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rightPanel.add(settingsBtn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tlačítko START
|
|
||||||
JButton startBtn = new JButton("▶ START");
|
JButton startBtn = new JButton("▶ START");
|
||||||
startBtn.setPreferredSize(new Dimension(90, 32));
|
startBtn.setPreferredSize(new Dimension(100, 32));
|
||||||
styleButton(startBtn, PRIMARY_GREEN, Color.WHITE, SMALL_FONT);
|
styleButton(startBtn, PRIMARY_GREEN, Color.WHITE, SMALL_FONT);
|
||||||
startBtn.addActionListener(startAction);
|
startBtn.addActionListener(startAction);
|
||||||
|
|
||||||
@ -669,51 +601,42 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
* Spustí autoklik
|
* Spustí autoklik
|
||||||
*/
|
*/
|
||||||
private void startAutoClick(JPanel autoClickCard) {
|
private void startAutoClick(JPanel autoClickCard) {
|
||||||
|
if (autoClickRunning) {
|
||||||
|
stopAutomation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
JOptionPane.showMessageDialog(this, "Automatizace již běží!", "Upozornění", JOptionPane.WARNING_MESSAGE);
|
JOptionPane.showMessageDialog(this, "Jiná automatizace již běží!", "Upozornění", JOptionPane.WARNING_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Načtení nastavení
|
// Načtení nastavení
|
||||||
JSpinner xSpinner = (JSpinner) autoClickCard.getClientProperty("xSpinner");
|
|
||||||
JSpinner ySpinner = (JSpinner) autoClickCard.getClientProperty("ySpinner");
|
|
||||||
JSpinner intervalSpinner = (JSpinner) autoClickCard.getClientProperty("intervalSpinner");
|
JSpinner intervalSpinner = (JSpinner) autoClickCard.getClientProperty("intervalSpinner");
|
||||||
JSpinner clickCountSpinner = (JSpinner) autoClickCard.getClientProperty("clickCountSpinner");
|
|
||||||
|
|
||||||
int x = (Integer) xSpinner.getValue();
|
|
||||||
int y = (Integer) ySpinner.getValue();
|
|
||||||
int interval = (Integer) intervalSpinner.getValue();
|
int interval = (Integer) intervalSpinner.getValue();
|
||||||
int clickCount = (Integer) clickCountSpinner.getValue();
|
|
||||||
|
|
||||||
// Uložení nastavení
|
// Uložení nastavení
|
||||||
settings.setProperty("autoklik.x", String.valueOf(x));
|
|
||||||
settings.setProperty("autoklik.y", String.valueOf(y));
|
|
||||||
settings.setProperty("autoklik.interval", String.valueOf(interval));
|
settings.setProperty("autoklik.interval", String.valueOf(interval));
|
||||||
settings.setProperty("autoklik.count", String.valueOf(clickCount));
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
|
|
||||||
// Uložit pozici myši před spuštěním
|
|
||||||
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
|
||||||
Point originalMousePosition = pointerInfo != null ? pointerInfo.getLocation() : null;
|
|
||||||
|
|
||||||
stopButton.setEnabled(true);
|
stopButton.setEnabled(true);
|
||||||
statusLabel.setText("Autoklik běží... (" + x + ", " + y + ")");
|
statusLabel.setText("Autokliker aktivní (Šipka dolů)...");
|
||||||
statusLabel.setForeground(new Color(255, 152, 0));
|
statusLabel.setForeground(new Color(255, 152, 0));
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
autoClickRunning = true;
|
autoClickRunning = true;
|
||||||
shouldStop = false;
|
shouldStop = false;
|
||||||
|
|
||||||
// Změnit barvu START tlačítka na červenou
|
// Změnit tlačítko na VYPNOUT
|
||||||
JButton startBtn = (JButton) autoClickCard.getClientProperty("startButton");
|
JButton startBtn = (JButton) autoClickCard.getClientProperty("startButton");
|
||||||
if (startBtn != null) {
|
if (startBtn != null) {
|
||||||
startBtn.setEnabled(false);
|
startBtn.setText("⏹ VYPNOUT");
|
||||||
styleButton(startBtn, PRIMARY_RED, Color.WHITE, SMALL_FONT);
|
styleButton(startBtn, PRIMARY_RED, Color.WHITE, SMALL_FONT);
|
||||||
}
|
}
|
||||||
|
|
||||||
logArea.append("\n========================================\n");
|
logArea.append("\n========================================\n");
|
||||||
logArea.append("SPOUŠTĚNÍ AUTOKLIKERU\n");
|
logArea.append("AUTOKLIKER AKTIVNÍ\n");
|
||||||
logArea.append("Pozice: (" + x + ", " + y + ")\n");
|
logArea.append("Interval: " + interval + "ms\n");
|
||||||
logArea.append("Interval: " + interval + "ms, Počet kliknutí: " + clickCount + "\n");
|
logArea.append("Ovládání: Stiskněte ŠIPKU NAHORU nebo DOLŮ pro zapnutí/vypnutí\n");
|
||||||
logArea.append("========================================\n\n");
|
logArea.append("========================================\n\n");
|
||||||
|
|
||||||
automationThread = new Thread(new Runnable() {
|
automationThread = new Thread(new Runnable() {
|
||||||
@ -721,42 +644,61 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
java.awt.Robot robot = new java.awt.Robot();
|
java.awt.Robot robot = new java.awt.Robot();
|
||||||
|
int clicksDone = 0;
|
||||||
|
boolean isClickingActive = false;
|
||||||
|
boolean wasKeyPressed = false;
|
||||||
|
long lastClickTime = 0;
|
||||||
|
long lastToggleTime = 0;
|
||||||
|
|
||||||
logArea.append("Spouštím autoklik...\n");
|
while (autoClickRunning && !shouldStop) {
|
||||||
|
// Kontrola obou šipek
|
||||||
|
boolean isKeyPressed = globalHotkey.isKeyPressed(KeyEvent.VK_DOWN) ||
|
||||||
|
globalHotkey.isKeyPressed(KeyEvent.VK_UP);
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
for (int i = 0; i < clickCount && autoClickRunning && !shouldStop; i++) {
|
// Detekce stisku (náběžná hrana) pro přepnutí stavu
|
||||||
// Přesunutí kurzoru na pozici
|
if (isKeyPressed && !wasKeyPressed && (currentTime - lastToggleTime > 200)) {
|
||||||
robot.mouseMove(x, y);
|
isClickingActive = !isClickingActive;
|
||||||
Thread.sleep(10);
|
lastToggleTime = currentTime;
|
||||||
|
|
||||||
// Klik
|
final boolean active = isClickingActive;
|
||||||
robot.mousePress(java.awt.event.InputEvent.BUTTON1_DOWN_MASK);
|
SwingUtilities.invokeLater(() -> {
|
||||||
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_DOWN_MASK);
|
logArea.append(active ? "▶ Klikání AKTIVOVÁNO šipkou\n" : "⏸ Klikání POZASTAVENO šipkou\n");
|
||||||
|
statusLabel.setText(active ? "Autokliker: KLIKÁM..." : "Autokliker: POZASTAVENO");
|
||||||
// Čekání mezi kliknutími
|
|
||||||
if (i < clickCount - 1 && !shouldStop) {
|
|
||||||
Thread.sleep(interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update progress každých 10 kliknutí
|
|
||||||
if ((i + 1) % 10 == 0 && !shouldStop) {
|
|
||||||
int progress = i + 1;
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
logArea.append(" Kliknutí: " + progress + "/" + clickCount + "\n");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isClickingActive) {
|
||||||
|
lastClickTime = 0; // Spustit klikání hned
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
wasKeyPressed = isKeyPressed;
|
||||||
|
|
||||||
|
if (isClickingActive) {
|
||||||
|
if (currentTime - lastClickTime >= interval) {
|
||||||
|
// Klik na aktuální pozici
|
||||||
|
robot.mousePress(java.awt.event.InputEvent.BUTTON1_DOWN_MASK);
|
||||||
|
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_DOWN_MASK);
|
||||||
|
|
||||||
|
clicksDone++;
|
||||||
|
if (clicksDone % 20 == 0) {
|
||||||
|
final int count = clicksDone;
|
||||||
|
SwingUtilities.invokeLater(() -> logArea.append(" Kliknutí: " + count + "\n"));
|
||||||
|
}
|
||||||
|
lastClickTime = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rychlá smyčka pro detekci kláves (10ms)
|
||||||
|
Thread.sleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shouldStop) {
|
if (!shouldStop) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusLabel.setText("Autoklik úspěšně dokončen!");
|
statusLabel.setText("Autokliker zastaven.");
|
||||||
statusLabel.setForeground(new Color(76, 175, 80));
|
statusLabel.setForeground(new Color(76, 175, 80));
|
||||||
logArea.append("\n✅ Autoklik úspěšně dokončen! Celkem kliknutí: " + clickCount + "\n");
|
logArea.append("\n✅ Autokliker byl vypnut.\n");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -767,25 +709,13 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusLabel.setText("Chyba!");
|
statusLabel.setText("Chyba autoklikeru!");
|
||||||
statusLabel.setForeground(new Color(244, 67, 54));
|
statusLabel.setForeground(new Color(244, 67, 54));
|
||||||
logArea.append("\n❌ Chyba: " + e.getMessage() + "\n");
|
logArea.append("\n❌ Chyba: " + e.getMessage() + "\n");
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// Vrátit myš na původní pozici
|
|
||||||
if (originalMousePosition != null) {
|
|
||||||
try {
|
|
||||||
java.awt.Robot robot = new java.awt.Robot();
|
|
||||||
robot.mouseMove(originalMousePosition.x, originalMousePosition.y);
|
|
||||||
logArea.append("🖱️ Myš vrácena na původní pozici: (" + originalMousePosition.x + ", " + originalMousePosition.y + ")\n");
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("Chyba při vracení myši: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -793,10 +723,10 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
autoClickRunning = false;
|
autoClickRunning = false;
|
||||||
stopButton.setEnabled(false);
|
stopButton.setEnabled(false);
|
||||||
|
|
||||||
// Vrátit barvu START tlačítka na zelenou
|
// Vrátit tlačítko na START
|
||||||
JButton btn = (JButton) autoClickCard.getClientProperty("startButton");
|
JButton btn = (JButton) autoClickCard.getClientProperty("startButton");
|
||||||
if (btn != null) {
|
if (btn != null) {
|
||||||
btn.setEnabled(true);
|
btn.setText("▶ START");
|
||||||
styleButton(btn, PRIMARY_GREEN, Color.WHITE, SMALL_FONT);
|
styleButton(btn, PRIMARY_GREEN, Color.WHITE, SMALL_FONT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,9 +85,48 @@ public class WindowFinder {
|
|||||||
IntByReference dest_x_return, IntByReference dest_y_return,
|
IntByReference dest_x_return, IntByReference dest_y_return,
|
||||||
PointerByReference child_return);
|
PointerByReference child_return);
|
||||||
|
|
||||||
|
// Globální klávesy
|
||||||
|
int XQueryKeymap(Pointer display, byte[] keys_return);
|
||||||
|
int XKeysymToKeycode(Pointer display, long keysym);
|
||||||
|
|
||||||
Pointer XFree(Pointer ptr);
|
Pointer XFree(Pointer ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zjistí, zda je klávesa stisknuta globálně (i mimo fokus aplikace)
|
||||||
|
* @param keysym X11 Keysym (např. 0xFF54 pro Down Arrow)
|
||||||
|
* @return true pokud je klávesa držena
|
||||||
|
*/
|
||||||
|
public static synchronized boolean isKeyPressedGlobally(long keysym) {
|
||||||
|
Pointer display = null;
|
||||||
|
try {
|
||||||
|
if (cachedDisplay != null) {
|
||||||
|
display = cachedDisplay;
|
||||||
|
} else {
|
||||||
|
display = X11.INSTANCE.XOpenDisplay(null);
|
||||||
|
if (display == null) return false;
|
||||||
|
cachedDisplay = display;
|
||||||
|
}
|
||||||
|
|
||||||
|
int keycode = X11.INSTANCE.XKeysymToKeycode(display, keysym);
|
||||||
|
if (keycode == 0) return false;
|
||||||
|
|
||||||
|
byte[] keys = new byte[32];
|
||||||
|
X11.INSTANCE.XQueryKeymap(display, keys);
|
||||||
|
|
||||||
|
// bitmask v XQueryKeymap: keycode / 8 je index bajtu, (keycode % 8) je pozice bitu
|
||||||
|
int byteIdx = keycode / 8;
|
||||||
|
int bitIdx = keycode % 8;
|
||||||
|
|
||||||
|
if (byteIdx >= 0 && byteIdx < 32) {
|
||||||
|
return (keys[byteIdx] & (1 << bitIdx)) != 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Najde okno podle jeho názvu a vrátí jeho bounds
|
* Najde okno podle jeho názvu a vrátí jeho bounds
|
||||||
* @param searchPattern Pattern pro hledání (substring názvu okna)
|
* @param searchPattern Pattern pro hledání (substring názvu okna)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user