diff --git a/src/com/esotericsoftware/clippy/Clippy.java b/src/com/esotericsoftware/clippy/Clippy.java index 0eaa922..c298d5f 100644 --- a/src/com/esotericsoftware/clippy/Clippy.java +++ b/src/com/esotericsoftware/clippy/Clippy.java @@ -44,6 +44,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.TimerTask; import javax.swing.KeyStroke; import javax.swing.UIManager; @@ -77,6 +78,7 @@ public class Clippy { final BreakWarning breakWarning; final Tobii tobii; boolean disabled; + boolean processDisabled; public Clippy () { instance = this; @@ -269,9 +271,36 @@ public void run () { if (WARN) warn("Unable to write PID file.", ex); } + if (config.processesDisable != null) checkProcesses(); + if (INFO) info("Started."); } + void checkProcesses () { + System.out.println(1); + + String process = Util.getRunningProcess(config.processesDisable); + if (process != null) { + if (!disabled) { + if (TRACE) trace("Disabled, process running: " + process); + setDisabled(true); + processDisabled = true; + } + } else if (processDisabled) { + processDisabled = false; + if (disabled) { + if (TRACE) trace("Enabled, process no longer running."); + setDisabled(false); + } + } + + Util.timer.schedule(new TimerTask() { + public void run () { + checkProcesses(); + } + }, config.processesCheckSeconds * 1000); + } + void upload () { String text = clipboard.getContents(); switch (clipboard.getDataType()) { @@ -290,10 +319,19 @@ void showPopup (KeyStroke keyStroke) { } void store (String text) { + if (config.processesDisableClipHistory != null) { + String process = Util.getRunningProcess(config.processesDisableClipHistory); + if (process != null) { + if (TRACE) trace("Not storing clipboard text, process running: " + process); + return; + } + } + if (text.length() > config.maxLengthToStore) { if (TRACE) trace("Text too large to store: " + text.length()); return; } + if (TRACE) trace("Store clipboard text: " + text.trim()); try { ClipConnection conn = db.getThreadConnection(); @@ -350,15 +388,17 @@ public int paste (String text) { return newID; } - public void setDisabled (boolean disabled) { - if (this.disabled == disabled) return; + public boolean setDisabled (boolean disabled) { + if (this.disabled == disabled) return false; this.disabled = disabled; if (INFO) info("Disabled: " + disabled); gamma.toggle(); breakWarning.toggle(); + processDisabled = false; + return true; } - public static void main (String[] args) throws Exception { + static public void main (String[] args) throws Exception { if (FindWindow(new WString("STATIC"), new WString("com.esotericsoftware.clippy")) != null) { if (ERROR) error("Already running."); return; diff --git a/src/com/esotericsoftware/clippy/Config.java b/src/com/esotericsoftware/clippy/Config.java index 3f4e590..ddcdfaf 100644 --- a/src/com/esotericsoftware/clippy/Config.java +++ b/src/com/esotericsoftware/clippy/Config.java @@ -23,27 +23,25 @@ import static com.esotericsoftware.clippy.util.Util.*; import static com.esotericsoftware.minlog.Log.*; -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map.Entry; - import com.esotericsoftware.clippy.PhilipsHue.PhilipsHueTimeline; import com.esotericsoftware.clippy.util.ColorTimeline; import com.esotericsoftware.clippy.util.Sun; import com.esotericsoftware.jsonbeans.Json; import com.esotericsoftware.jsonbeans.JsonException; import com.esotericsoftware.jsonbeans.JsonReader; -import com.esotericsoftware.jsonbeans.JsonSerializable; import com.esotericsoftware.jsonbeans.JsonValue; import com.esotericsoftware.jsonbeans.JsonWriter; import com.esotericsoftware.minlog.Log; +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map.Entry; + /** @author Nathan Sweet */ public class Config { static public final Clippy clippy = Clippy.instance; @@ -63,7 +61,11 @@ public class Config { public boolean popupPastes = true; public String font = "Consolas-14"; - public int clipBackupDays = 7; + public String[] processesDisableClipHistory; + public String[] processesDisable; + public int processesCheckSeconds = 25; + + public int clipBackupDays = 3; public String screenshotHotkey = null; public String screenshotAppHotkey = "ctrl alt shift BACK_SLASH"; diff --git a/src/com/esotericsoftware/clippy/Win.java b/src/com/esotericsoftware/clippy/Win.java index 96a822a..507faa6 100644 --- a/src/com/esotericsoftware/clippy/Win.java +++ b/src/com/esotericsoftware/clippy/Win.java @@ -32,6 +32,7 @@ import com.sun.jna.Structure; import com.sun.jna.WString; import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.W32APIOptions; /** @author Nathan Sweet */ @@ -367,4 +368,37 @@ protected List getFieldOrder () { return Arrays.asList("Red", "Green", "Blue"); } } + + static public class Wtsapi32 { + static { + Native.register(NativeLibrary.getInstance("wtsapi32", W32APIOptions.DEFAULT_OPTIONS)); + } + + static public final int WTS_CURRENT_SERVER_HANDLE = 0; + + static public native boolean WTSEnumerateProcesses (int hServer, Pointer Reserved, int Version, + PointerByReference ppProcessInfo, IntByReference pCount); + + static public native void WTSFreeMemory (Pointer pMemory); + } + + static public class WTS_PROCESS_INFO extends Structure { + public int SessionId; + public int ProcessId; + public WString pProcessName; + public Pointer pUserSid; + + private WTS_PROCESS_INFO () { + } + + public WTS_PROCESS_INFO (Pointer p) { + super(p); + } + + protected List getFieldOrder () { + return Arrays.asList("SessionId", "ProcessId", "pProcessName", "pUserSid"); + } + + static public final int size = new WTS_PROCESS_INFO().size(); + } } diff --git a/src/com/esotericsoftware/clippy/util/Util.java b/src/com/esotericsoftware/clippy/util/Util.java index 4bf44ba..b22b825 100644 --- a/src/com/esotericsoftware/clippy/util/Util.java +++ b/src/com/esotericsoftware/clippy/util/Util.java @@ -23,9 +23,18 @@ import static com.esotericsoftware.clippy.Win.User32.*; import static com.esotericsoftware.minlog.Log.*; -import java.awt.GraphicsEnvironment; -import java.awt.Point; -import java.awt.Robot; +import com.esotericsoftware.clippy.Config.ColorTime; +import com.esotericsoftware.clippy.Config.ColorTimesReference; +import com.esotericsoftware.clippy.Win.POINT; +import com.esotericsoftware.clippy.Win.WTS_PROCESS_INFO; +import com.esotericsoftware.clippy.Win.Wtsapi32; +import com.esotericsoftware.jsonbeans.Json; +import com.esotericsoftware.jsonbeans.JsonException; +import com.esotericsoftware.jsonbeans.JsonSerializer; +import com.esotericsoftware.jsonbeans.JsonValue; +import com.esotericsoftware.jsonbeans.JsonValue.PrettyPrintSettings; +import com.esotericsoftware.jsonbeans.OutputType; + import java.io.Closeable; import java.io.File; import java.io.FileInputStream; @@ -48,15 +57,13 @@ import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; -import com.esotericsoftware.clippy.Config.ColorTime; -import com.esotericsoftware.clippy.Config.ColorTimesReference; -import com.esotericsoftware.clippy.Win.POINT; -import com.esotericsoftware.jsonbeans.Json; -import com.esotericsoftware.jsonbeans.JsonException; -import com.esotericsoftware.jsonbeans.JsonSerializer; -import com.esotericsoftware.jsonbeans.JsonValue; -import com.esotericsoftware.jsonbeans.JsonValue.PrettyPrintSettings; -import com.esotericsoftware.jsonbeans.OutputType; +import com.sun.jna.Pointer; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Robot; /** @author Nathan Sweet */ public class Util { @@ -331,4 +338,27 @@ static public void writeJson (Object object, File file) throws IOException { writer.write(json.prettyPrint(object, pretty)); writer.close(); } + + /** @param names May be null. + * @return May be null. */ + static public String getRunningProcess (String... names) { + if (names == null) return null; + + PointerByReference infosOut = new PointerByReference(); + IntByReference countOut = new IntByReference(); + if (!Wtsapi32.WTSEnumerateProcesses(Wtsapi32.WTS_CURRENT_SERVER_HANDLE, null, 1, infosOut, countOut)) return null; + + Pointer infos = infosOut.getValue(); + try { + int size = WTS_PROCESS_INFO.size, offset = 0; + for (int i = 0, n = countOut.getValue(); i < n; i++, offset += size) { + String name = new WTS_PROCESS_INFO(infos.share(offset)).readField("pProcessName").toString(); + for (int ii = 0, nn = names.length; ii < nn; ii++) + if (name.equalsIgnoreCase(names[ii])) return name; + } + return null; + } finally { + Wtsapi32.WTSFreeMemory(infos); + } + } }