transfer fixes
This commit is contained in:
parent
162aa6d7ab
commit
444fd73bb2
@ -1,5 +1,5 @@
|
|||||||
#Pokémon GO Automatizace - Nastavení
|
#Pokémon GO Automatizace - Nastavení
|
||||||
#Fri Dec 19 21:53:30 CET 2025
|
#Fri Dec 19 22:55:32 CET 2025
|
||||||
autoklik.count=500
|
autoklik.count=500
|
||||||
window.width=807
|
window.width=807
|
||||||
transfer.delay=0
|
transfer.delay=0
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import java.awt.AWTException;
|
|||||||
import java.awt.GraphicsDevice;
|
import java.awt.GraphicsDevice;
|
||||||
import java.awt.GraphicsEnvironment;
|
import java.awt.GraphicsEnvironment;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.MouseInfo;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
|
import java.awt.PointerInfo;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Robot;
|
import java.awt.Robot;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@ -32,6 +34,7 @@ public class PokemonGoAutomation {
|
|||||||
private static final int DELAY_BETWEEN_CLICKS = 100; // ms
|
private static final int DELAY_BETWEEN_CLICKS = 100; // ms
|
||||||
private static final int DELAY_AFTER_ACTION = 100; // ms
|
private static final int DELAY_AFTER_ACTION = 100; // ms
|
||||||
private int transferredPokemonCount = 0; // Počet transfernutých pokémonů
|
private int transferredPokemonCount = 0; // Počet transfernutých pokémonů
|
||||||
|
private Point initialMousePosition = null; // Pozice kurzoru před začátkem automatizace
|
||||||
|
|
||||||
public PokemonGoAutomation() throws AWTException {
|
public PokemonGoAutomation() throws AWTException {
|
||||||
this.robot = new Robot();
|
this.robot = new Robot();
|
||||||
@ -524,6 +527,13 @@ public class PokemonGoAutomation {
|
|||||||
System.out.println("Spouštím Transfer automatizaci - Počet pokémonů: " + totalPokemonCount + ", Čekání: "
|
System.out.println("Spouštím Transfer automatizaci - Počet pokémonů: " + totalPokemonCount + ", Čekání: "
|
||||||
+ delaySeconds + "s");
|
+ delaySeconds + "s");
|
||||||
|
|
||||||
|
// Uložit aktuální pozici kurzoru
|
||||||
|
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
||||||
|
initialMousePosition = pointerInfo != null ? pointerInfo.getLocation() : null;
|
||||||
|
if (initialMousePosition != null) {
|
||||||
|
System.out.println("Uložena počáteční pozice kurzoru: " + initialMousePosition);
|
||||||
|
}
|
||||||
|
|
||||||
if (!findPokemonGoWindow()) {
|
if (!findPokemonGoWindow()) {
|
||||||
System.err.println("Nepodařilo se najít okno Pokémon GO!");
|
System.err.println("Nepodařilo se najít okno Pokémon GO!");
|
||||||
return;
|
return;
|
||||||
@ -537,7 +547,8 @@ public class PokemonGoAutomation {
|
|||||||
int transferredCount = 0;
|
int transferredCount = 0;
|
||||||
|
|
||||||
// Transferovat dokud nedosáhneme požadovaného počtu
|
// Transferovat dokud nedosáhneme požadovaného počtu
|
||||||
while (transferredCount < totalPokemonCount) {
|
try {
|
||||||
|
while (transferredCount < totalPokemonCount) {
|
||||||
// Kontrola přerušení
|
// Kontrola přerušení
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
System.out.println("\n⚠️ Automatizace byla přerušena!");
|
System.out.println("\n⚠️ Automatizace byla přerušena!");
|
||||||
@ -582,11 +593,22 @@ public class PokemonGoAutomation {
|
|||||||
while (System.currentTimeMillis() < endTime) {
|
while (System.currentTimeMillis() < endTime) {
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (Thread.currentThread().isInterrupted()) {
|
||||||
System.out.println("\n⚠️ Automatizace byla přerušena během přestávky!");
|
System.out.println("\n⚠️ Automatizace byla přerušena během přestávky!");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
robot.delay(100);
|
robot.delay(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Obnovit pozici kurzoru
|
||||||
|
if (initialMousePosition != null) {
|
||||||
|
try {
|
||||||
|
robot.mouseMove(initialMousePosition.x, initialMousePosition.y);
|
||||||
|
System.out.println("Kurzor vrácen na počáteční pozici: " + initialMousePosition);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Chyba při obnovení pozice kurzoru: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("\n✅ Transfer automatizace dokončena! Transferováno: " + transferredCount + " pokémonů");
|
System.out.println("\n✅ Transfer automatizace dokončena! Transferováno: " + transferredCount + " pokémonů");
|
||||||
@ -669,6 +691,30 @@ public class PokemonGoAutomation {
|
|||||||
return new Point(absoluteX, absoluteY);
|
return new Point(absoluteX, absoluteY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vyčistí všechny prostředky používané automatizací
|
||||||
|
* Volat po skončení automatizace
|
||||||
|
*/
|
||||||
|
public void cleanup() {
|
||||||
|
try {
|
||||||
|
System.out.println("Čištění prostředků automatizace...");
|
||||||
|
|
||||||
|
// Uvolnit reference na obrázky
|
||||||
|
t1Template = null;
|
||||||
|
t2Template = null;
|
||||||
|
t3Template = null;
|
||||||
|
pok1Template = null;
|
||||||
|
includeTemplate = null;
|
||||||
|
windowBounds = null;
|
||||||
|
|
||||||
|
// Explicitně vyvolat garbage collector
|
||||||
|
System.gc();
|
||||||
|
System.out.println("Prostředky automatizace vyčištěny");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Chyba při čištění prostředků: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("=== Pokémon GO Automatizační Nástroj ===");
|
System.out.println("=== Pokémon GO Automatizační Nástroj ===");
|
||||||
System.out.println("Ujistěte se, že je aplikace Pokémon GO spuštěná...");
|
System.out.println("Ujistěte se, že je aplikace Pokémon GO spuštěná...");
|
||||||
|
|||||||
@ -31,7 +31,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
private static final String CONFIG_FILE = "pgo-automat-settings.properties";
|
private static final String CONFIG_FILE = "pgo-automat-settings.properties";
|
||||||
private static final String VERSION = "1.0.2";
|
private static final String VERSION = "1.0.2";
|
||||||
private Properties settings;
|
private Properties settings;
|
||||||
private JSpinner countSpinner;
|
private JComboBox<Integer> countComboBox;
|
||||||
private JSpinner delaySpinner;
|
private JSpinner delaySpinner;
|
||||||
|
|
||||||
private static final Font TITLE_FONT = new Font("Segoe UI", Font.BOLD, 18);
|
private static final Font TITLE_FONT = new Font("Segoe UI", Font.BOLD, 18);
|
||||||
@ -330,21 +330,37 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
centerPanel.setOpaque(true);
|
centerPanel.setOpaque(true);
|
||||||
|
|
||||||
if (title.contains("TRANSFER")) {
|
if (title.contains("TRANSFER")) {
|
||||||
countSpinner = new JSpinner(new SpinnerNumberModel(
|
// Načíst hodnotu a zajistit, že je v platném rozsahu nebo v seznamu povolených hodnot
|
||||||
Integer.parseInt(settings.getProperty("transfer.count", "9")),
|
int savedCount = Integer.parseInt(settings.getProperty("transfer.count", "12"));
|
||||||
1, 999, 1
|
// Povolené hodnoty: 1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96
|
||||||
));
|
int[] validCounts = {1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96};
|
||||||
countSpinner.setPreferredSize(new Dimension(64, 26));
|
boolean isValid = false;
|
||||||
|
for (int count : validCounts) {
|
||||||
|
if (savedCount == count) {
|
||||||
|
isValid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isValid) {
|
||||||
|
savedCount = 12; // Nastavit na výchozí, pokud není v seznamu povolených
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vytvořit dropdown s hodnotami 1, 3, 6, 12, 24, 36, ..., 96
|
||||||
|
Integer[] counts = {1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96};
|
||||||
|
countComboBox = new JComboBox<>(counts);
|
||||||
|
countComboBox.setSelectedItem(savedCount);
|
||||||
|
countComboBox.setPreferredSize(new Dimension(70, 26));
|
||||||
|
|
||||||
delaySpinner = new JSpinner(new SpinnerNumberModel(
|
delaySpinner = new JSpinner(new SpinnerNumberModel(
|
||||||
Integer.parseInt(settings.getProperty("transfer.delay", "2")),
|
Integer.parseInt(settings.getProperty("transfer.delay", "2")),
|
||||||
0, 60, 1
|
0, 60, 1
|
||||||
));
|
));
|
||||||
delaySpinner.setPreferredSize(new Dimension(64, 26));
|
delaySpinner.setPreferredSize(new Dimension(64, 26));
|
||||||
|
|
||||||
card.putClientProperty("countSpinner", countSpinner);
|
card.putClientProperty("countComboBox", countComboBox);
|
||||||
card.putClientProperty("delaySpinner", delaySpinner);
|
card.putClientProperty("delaySpinner", delaySpinner);
|
||||||
|
|
||||||
centerPanel.add(createFieldPanel("Počet:", countSpinner));
|
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(
|
JSpinner xSpinner = new JSpinner(new SpinnerNumberModel(
|
||||||
@ -524,10 +540,10 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Získat počet pokémonů a čekání z GUI
|
// Získat počet pokémonů a čekání z GUI
|
||||||
JSpinner countSpinner = (JSpinner) transferCard.getClientProperty("countSpinner");
|
JComboBox<Integer> countComboBox = (JComboBox<Integer>) transferCard.getClientProperty("countComboBox");
|
||||||
JSpinner delaySpinner = (JSpinner) transferCard.getClientProperty("delaySpinner");
|
JSpinner delaySpinner = (JSpinner) transferCard.getClientProperty("delaySpinner");
|
||||||
|
|
||||||
int pokemonCount = (Integer) countSpinner.getValue();
|
int pokemonCount = (Integer) countComboBox.getSelectedItem();
|
||||||
int delaySeconds = (Integer) delaySpinner.getValue();
|
int delaySeconds = (Integer) delaySpinner.getValue();
|
||||||
|
|
||||||
stopButton.setEnabled(true);
|
stopButton.setEnabled(true);
|
||||||
@ -599,6 +615,18 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
|
// Čistit prostředky po automatizaci
|
||||||
|
try {
|
||||||
|
if (automation != null) {
|
||||||
|
automation.cleanup();
|
||||||
|
}
|
||||||
|
// Také vyčistit WindowFinder resources
|
||||||
|
WindowFinder.cleanup();
|
||||||
|
System.gc();
|
||||||
|
} catch (Exception cleanupEx) {
|
||||||
|
System.err.println("Chyba při čištění: " + cleanupEx.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -773,7 +801,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
|
|
||||||
// Výchozí hodnoty, pokud nastavení neexistují
|
// Výchozí hodnoty, pokud nastavení neexistují
|
||||||
if (!settings.containsKey("transfer.count")) {
|
if (!settings.containsKey("transfer.count")) {
|
||||||
settings.setProperty("transfer.count", "9");
|
settings.setProperty("transfer.count", "12");
|
||||||
}
|
}
|
||||||
if (!settings.containsKey("transfer.delay")) {
|
if (!settings.containsKey("transfer.delay")) {
|
||||||
settings.setProperty("transfer.delay", "2");
|
settings.setProperty("transfer.delay", "2");
|
||||||
@ -796,9 +824,9 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
* Uloží aktuální nastavení do souboru
|
* Uloží aktuální nastavení do souboru
|
||||||
*/
|
*/
|
||||||
private void saveSettings() {
|
private void saveSettings() {
|
||||||
// Uložení hodnot z spinnerů
|
// Uložení hodnot z combo boxu a spinneru
|
||||||
if (countSpinner != null) {
|
if (countComboBox != null) {
|
||||||
settings.setProperty("transfer.count", countSpinner.getValue().toString());
|
settings.setProperty("transfer.count", countComboBox.getSelectedItem().toString());
|
||||||
}
|
}
|
||||||
if (delaySpinner != null) {
|
if (delaySpinner != null) {
|
||||||
settings.setProperty("transfer.delay", delaySpinner.getValue().toString());
|
settings.setProperty("transfer.delay", delaySpinner.getValue().toString());
|
||||||
@ -819,11 +847,32 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
// Nastavit shutdown hook pro bezpečné ukončení
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
System.out.println("Aplikace se vypíná...");
|
||||||
|
// Vyčistit X11 resources
|
||||||
|
try {
|
||||||
|
WindowFinder.cleanup();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Chyba při čištění WindowFinder: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
PokemonGoGUI frame = new PokemonGoGUI();
|
PokemonGoGUI frame = new PokemonGoGUI();
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
// Nastavit window listener pro čisté ukončení
|
||||||
|
frame.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
System.out.println("Zavírám okno...");
|
||||||
|
frame.saveSettings();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,20 +22,11 @@ public class PositionPicker extends JWindow {
|
|||||||
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||||
Rectangle screenBounds = gd.getDefaultConfiguration().getBounds();
|
Rectangle screenBounds = gd.getDefaultConfiguration().getBounds();
|
||||||
|
|
||||||
// Zjistit insets - offset zp ůsobený OS panelem/dashboardem
|
// Pokrýt celou obrazovku bez omezení insets
|
||||||
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration());
|
// (protože vrátíme absolutní globální souřadnice, ne relativní)
|
||||||
System.out.println("PositionPicker insets: top=" + insets.top + ", left=" + insets.left);
|
setBounds(screenBounds);
|
||||||
|
|
||||||
// Aplikovat insets na bounds
|
System.out.println("PositionPicker vytvořen: " + screenBounds);
|
||||||
Rectangle bounds = new Rectangle(
|
|
||||||
screenBounds.x + insets.left,
|
|
||||||
screenBounds.y + insets.top,
|
|
||||||
screenBounds.width - insets.left - insets.right,
|
|
||||||
screenBounds.height - insets.top - insets.bottom
|
|
||||||
);
|
|
||||||
setBounds(bounds);
|
|
||||||
|
|
||||||
System.out.println("PositionPicker vytvořen: " + bounds);
|
|
||||||
|
|
||||||
setFocusable(true);
|
setFocusable(true);
|
||||||
setBackground(new Color(0, 0, 0, 0));
|
setBackground(new Color(0, 0, 0, 0));
|
||||||
@ -69,7 +60,11 @@ public class PositionPicker extends JWindow {
|
|||||||
panel.addMouseListener(new MouseAdapter() {
|
panel.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(MouseEvent e) {
|
||||||
selectedPosition = new Point(e.getX(), e.getY());
|
// Vrátit absolutní globální souřadnice na obrazovce
|
||||||
|
selectedPosition = new Point(
|
||||||
|
screenBounds.x + e.getX(),
|
||||||
|
screenBounds.y + e.getY()
|
||||||
|
);
|
||||||
positionSelected = true;
|
positionSelected = true;
|
||||||
System.out.println("✅ Pozice vybrána: " + selectedPosition);
|
System.out.println("✅ Pozice vybrána: " + selectedPosition);
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
|
|||||||
@ -16,6 +16,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class WindowFinder {
|
public class WindowFinder {
|
||||||
|
|
||||||
|
private static Pointer cachedDisplay = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* X11 native library interface
|
* X11 native library interface
|
||||||
*/
|
*/
|
||||||
@ -23,7 +25,7 @@ public class WindowFinder {
|
|||||||
X11 INSTANCE = Native.load("X11", X11.class);
|
X11 INSTANCE = Native.load("X11", X11.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* X11 Window Attributes struktura
|
* X11 Window Attributes struktura - přesná kopie z X11/Xlib.h
|
||||||
*/
|
*/
|
||||||
class XWindowAttributes extends Structure {
|
class XWindowAttributes extends Structure {
|
||||||
public int x;
|
public int x;
|
||||||
@ -32,31 +34,32 @@ public class WindowFinder {
|
|||||||
public int height;
|
public int height;
|
||||||
public int border_width;
|
public int border_width;
|
||||||
public int depth;
|
public int depth;
|
||||||
public Pointer visual;
|
public Pointer visual; // Visual* - opaque pointer
|
||||||
public Pointer root;
|
public long root; // Window (XID)
|
||||||
public int class_;
|
public int class_; // int, not pointer
|
||||||
public int bit_gravity;
|
public int bit_gravity;
|
||||||
public int win_gravity;
|
public int win_gravity;
|
||||||
public int backing_pixel;
|
|
||||||
public int backing_planes;
|
|
||||||
public int backing_store;
|
public int backing_store;
|
||||||
public long backing_pixel_unused;
|
public long backing_planes;
|
||||||
public int save_under;
|
public long backing_pixel;
|
||||||
public Pointer colormap;
|
public boolean save_under; // Bool - should be boolean
|
||||||
public int map_installed;
|
public long colormap; // Colormap (XID) - should be long
|
||||||
|
public boolean map_installed; // Bool - should be boolean
|
||||||
public int map_state;
|
public int map_state;
|
||||||
public long all_event_masks;
|
public long all_event_masks;
|
||||||
public long your_event_mask;
|
public long your_event_mask;
|
||||||
public long do_not_propagate_mask;
|
public long do_not_propagate_mask;
|
||||||
|
public boolean override_redirect; // Bool - missing field
|
||||||
|
public Pointer screen; // Screen* - opaque pointer, missing field
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<String> getFieldOrder() {
|
protected List<String> getFieldOrder() {
|
||||||
return Arrays.asList("x", "y", "width", "height", "border_width", "depth",
|
return Arrays.asList("x", "y", "width", "height", "border_width", "depth",
|
||||||
"visual", "root", "class_", "bit_gravity", "win_gravity",
|
"visual", "root", "class_", "bit_gravity", "win_gravity",
|
||||||
"backing_pixel", "backing_planes", "backing_store",
|
"backing_store", "backing_planes", "backing_pixel",
|
||||||
"backing_pixel_unused", "save_under", "colormap",
|
"save_under", "colormap", "map_installed", "map_state",
|
||||||
"map_installed", "map_state", "all_event_masks",
|
"all_event_masks", "your_event_mask", "do_not_propagate_mask",
|
||||||
"your_event_mask", "do_not_propagate_mask");
|
"override_redirect", "screen");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,16 +87,23 @@ public class WindowFinder {
|
|||||||
* @param searchPattern Pattern pro hledání (substring názvu okna)
|
* @param searchPattern Pattern pro hledání (substring názvu okna)
|
||||||
* @return Rectangle s pozicí a velikostí okna, nebo null pokud nenalezeno
|
* @return Rectangle s pozicí a velikostí okna, nebo null pokud nenalezeno
|
||||||
*/
|
*/
|
||||||
public static Rectangle findWindowByName(String searchPattern) {
|
public static synchronized Rectangle findWindowByName(String searchPattern) {
|
||||||
Pointer display = null;
|
Pointer display = null;
|
||||||
try {
|
|
||||||
display = X11.INSTANCE.XOpenDisplay(null);
|
|
||||||
if (display == null) {
|
|
||||||
System.out.println("WindowFinder: Nelze se připojit k X11 displei");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("WindowFinder: Připojen k X11 displayu");
|
try {
|
||||||
|
// Použít cachedDisplay pokud existuje, nebo otevřít nový
|
||||||
|
if (cachedDisplay != null) {
|
||||||
|
display = cachedDisplay;
|
||||||
|
System.out.println("WindowFinder: Používám cachovaný X11 display");
|
||||||
|
} else {
|
||||||
|
display = X11.INSTANCE.XOpenDisplay(null);
|
||||||
|
if (display == null) {
|
||||||
|
System.out.println("WindowFinder: Nelze se připojit k X11 displei");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
cachedDisplay = display;
|
||||||
|
System.out.println("WindowFinder: Připojen k X11 displayu a uložen v cache");
|
||||||
|
}
|
||||||
|
|
||||||
long rootWindow = X11.INSTANCE.XDefaultRootWindow(display);
|
long rootWindow = X11.INSTANCE.XDefaultRootWindow(display);
|
||||||
long[] foundWindow = new long[1];
|
long[] foundWindow = new long[1];
|
||||||
@ -115,15 +125,16 @@ public class WindowFinder {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("WindowFinder - Chyba: " + e.getMessage());
|
System.err.println("WindowFinder - Chyba: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return null;
|
// Pokud dojde k chybě, vynulovat cache a zavřít display
|
||||||
} finally {
|
if (display != null && display == cachedDisplay) {
|
||||||
if (display != null) {
|
|
||||||
try {
|
try {
|
||||||
X11.INSTANCE.XCloseDisplay(display);
|
X11.INSTANCE.XCloseDisplay(display);
|
||||||
} catch (Exception e) {
|
cachedDisplay = null;
|
||||||
System.err.println("WindowFinder - Chyba při zavírání displeje: " + e.getMessage());
|
} catch (Exception ex) {
|
||||||
|
System.err.println("WindowFinder - Chyba při zavírání displeje: " + ex.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,11 +159,12 @@ public class WindowFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hledat v potomcích
|
// Hledat v potomcích
|
||||||
|
PointerByReference children_return = new PointerByReference();
|
||||||
|
IntByReference nchildren_return = new IntByReference();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PointerByReference root_return = new PointerByReference();
|
PointerByReference root_return = new PointerByReference();
|
||||||
PointerByReference parent_return = new PointerByReference();
|
PointerByReference parent_return = new PointerByReference();
|
||||||
PointerByReference children_return = new PointerByReference();
|
|
||||||
IntByReference nchildren_return = new IntByReference();
|
|
||||||
|
|
||||||
int status = X11.INSTANCE.XQueryTree(display, window, root_return, parent_return,
|
int status = X11.INSTANCE.XQueryTree(display, window, root_return, parent_return,
|
||||||
children_return, nchildren_return);
|
children_return, nchildren_return);
|
||||||
@ -171,8 +183,8 @@ public class WindowFinder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uvolnit paměť
|
// Don't call XFree - it can cause heap corruption
|
||||||
X11.INSTANCE.XFree(childrenPtr);
|
// X11.INSTANCE.XFree(childrenPtr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -184,17 +196,21 @@ public class WindowFinder {
|
|||||||
* Získá jméno okna jako String
|
* Získá jméno okna jako String
|
||||||
*/
|
*/
|
||||||
private static String getWindowNameString(Pointer display, long window) {
|
private static String getWindowNameString(Pointer display, long window) {
|
||||||
|
PointerByReference namePtr = new PointerByReference();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PointerByReference namePtr = new PointerByReference();
|
|
||||||
int status = X11.INSTANCE.XFetchName(display, window, namePtr);
|
int status = X11.INSTANCE.XFetchName(display, window, namePtr);
|
||||||
|
|
||||||
if (status != 0 && namePtr.getValue() != null) {
|
if (status != 0) {
|
||||||
String name = namePtr.getValue().getString(0);
|
Pointer actualNamePtr = namePtr.getValue();
|
||||||
if (name != null && !name.isEmpty()) {
|
if (actualNamePtr != null) {
|
||||||
X11.INSTANCE.XFree(namePtr.getValue());
|
String name = actualNamePtr.getString(0);
|
||||||
return name;
|
|
||||||
|
// Don't call XFree - it can cause heap corruption
|
||||||
|
// X11.INSTANCE.XFree(actualNamePtr);
|
||||||
|
|
||||||
|
return (name != null && !name.isEmpty()) ? name : null;
|
||||||
}
|
}
|
||||||
X11.INSTANCE.XFree(namePtr.getValue());
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Ignorovat chyby
|
// Ignorovat chyby
|
||||||
@ -228,4 +244,21 @@ public class WindowFinder {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ukončí X11 display connection a vyčistí cache
|
||||||
|
* Volat při shutdown aplikace
|
||||||
|
*/
|
||||||
|
public static synchronized void cleanup() {
|
||||||
|
if (cachedDisplay != null) {
|
||||||
|
try {
|
||||||
|
X11.INSTANCE.XCloseDisplay(cachedDisplay);
|
||||||
|
System.out.println("WindowFinder: X11 display uzavřen a cache vyčištěn");
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("WindowFinder - Chyba při zavírání displeje: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
cachedDisplay = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user