Monitor system clipboard changes in electron

Time:2021-9-17

preface

To complete the clipboard history function, consult the electronic clipboard document. No hook event for clipboard changes was found, so I decided to implement one myself.

electronRead inClipboard content API, you can use this API to encapsulate the listening timer method. The specific logic is as follows:

Use the timer to constantly judge whether the contents are the same, if not. Execute clipboard change callback

Write a clipboard Observer class. When instantiating, the incoming message / picture change callback may bring performance burden. Therefore, it is also necessary to support the incoming custom listening interval.

The returned instance should support the methods of pause and continue listening.

Write clipboard Observer class

First, define the interface of constructor parameters

import { clipboard, NativeImage } from 'electron';

interface Options {
  //Interval of timer obtaining content judgment
  duration?: number;
  //Text change callback
  textChange?: (text: string, beforeText: string) => void;
  //Picture change callback
  imageChange?: (image: NativeImage, beforeImage: NativeImage) => void;
}

Then define the class and write the logic and exposed API in the constructor

class ClipboardObserver {
  //Timer
  timer: NodeJS.Timeout;
  //Text before change (used to compare newly obtained clipboard text)
  beforeText: string;
  //Changed picture (used to compare the newly obtained clipboard picture)
  beforeImage: NativeImage;

  duration = 500;
  textChange: (text: string, beforeText: string) => void;
  imageChange: (image: NativeImage, beforeImage: NativeImage) => void;

  constructor(options: Options) {
    //Get the incoming configuration and save it to the properties
    const { duration, textChange, imageChange } = options;

    this.duration = duration;
    this.textChange = textChange;
    this.imageChange = imageChange;

    //Judge the incoming callback and start the execution timer by default
    if (this.textChange || this.imageChange) {
      this.start();
    }
  }

  /**
   *Start
   */
  start(): void {
    //Record the current contents of the clipboard
    this.setClipboardDefaultValue();
    //Set timer
    this.setTimer();
  }

  /**
   *Pause
   */
  stop(): void {
    //Clear timer
    this.setTimer();
  }
}

clearTimerResponsible for callingclearIntervalTo clear the timer,setClipboardDefaultValueIt is responsible for setting the content of the last change recorded in the instance.

class ClipboardObserver {
  ...

  /**
   *Clear timer
   */
  clearTimer(): void {
    clearInterval(this.timer);
  }

  /**
   *Set clipboard defaults
   */
  setClipboardDefaultValue(): void {
    if (this.textChange) {
      //Method of reading text from electronic clipboard
      this.beforeText = clipboard.readText();
    }
    if (this.imageChange) {
      //Method of reading pictures from electronic clipboard
      this.beforeImage = clipboard.readImage();
    }
  }
}

setTimerCompare the core logic, set the timer, and judge whether the content changes in each round of timer callback. If the content changes, execute the content change callback.

class ClipboardObserver {
  ...

  /**
   *Set timer
   */
  setTimer(): void {
    //Set timer
    this.timer = setInterval(() => {
      if (this.textChange) {
        const text = clipboard.readText();
        //Determine whether the content is different from the last read content
        if (this.isDiffText(this.beforeText, text)) {
          //Execute change callback
          this.textChange(text, this.beforeText);
          //Record this content
          this.beforeText = text;
        }
      }

      if (this.imageChange) {
        const image = clipboard.readImage();
        //Determine whether the content is different from the last read content
        if (this.isDiffImage(this.beforeImage, image)) {
          //Execute change callback
          this.imageChange(image, this.beforeImage);
          //Record this content
          this.beforeImage = image;
        }
      }
    }, this.duration);
  }

  /**
   *Judge whether the content is inconsistent
   * @param beforeText
   * @param afterText
   * @returns
   */
  isDiffText(beforeText: string, afterText: string): boolean {
    return afterText && beforeText !== afterText;
  }

  /**
   *Judge whether the pictures are inconsistent
   * @param beforeImage
   * @param afterImage
   * @returns
   */
  isDiffImage(beforeImage: NativeImage, afterImage: NativeImage): boolean {
    return afterImage && !afterImage.isEmpty() && beforeImage.toDataURL() !== afterImage.toDataURL();
  }
}

Finish work

At this point, the logic of the clipboard Observer class has been completed. We can eat this in code

const clipboardObserver = new ClipboardObserver({
  textChange: (text: string, beforeText: string) => {
    //Logic for handling text changes
  },
  imageChange: (image: Electron.NativeImage, beforeText: Electron.NativeImage) => {
    //Logic for handling picture changes
  }
});

//You can also pause
clipboardObserver.stop();

//You can start again
clipboardObserver.start();

The project has been open source toelectron-clipboard-observerYes. You can copy code into a project for use

You can also install dependencies in a projectelectron-clipboard-observerAfter installation, it can be directly referenced and used in the project.

npm install electron-clipboard-observer

perhaps

yarn add electron-clipboard-observer

use

import ClipboardObserver from "electron-clipboard-observer"

const clipboardObserver = new ClipboardObserver({
    textChange() {},
    imageChange() {}
})

Project address

Code warehouse

npm

Recommended Today

Seven Python code review tools recommended

althoughPythonLanguage is one of the most flexible development languages at present, but developers often abuse its flexibility and even violate relevant standards. So PythoncodeThe following common quality problems often occur: Some unused modules have been imported Function is missing arguments in various calls The appropriate format indentation is missing Missing appropriate spaces before and after […]