Skip to content

Instantly share code, notes, and snippets.

@Necroforger
Last active August 31, 2018 22:55
Show Gist options
  • Save Necroforger/3f1d16f78578b24ae3133954c64cc933 to your computer and use it in GitHub Desktop.
Save Necroforger/3f1d16f78578b24ae3133954c64cc933 to your computer and use it in GitHub Desktop.
Sets windows as always on top and borderless with hotkeys. Also allows you to drag them around
var robot = require("robot-js");
const DRAG_ENABLED = true // enable dragging
const DRAG_BUTTON = robot.BUTTON_LEFT; // Mouse button required to drag windows
const DRAG_REQUIRE_ALT = false; // Require alt to be pressed to drag a window
const DRAG_TELEPORT_MOUSE = true; // Teleport the mouse to the bottom of the video to prevent it from pausing when dragging
const DRAG_SENSITIVITY = 30; // Minimum distance mouse is required to move after clicking to drag window
const DRAG_REQUIRE_BORDERLESS = true; // Require that a window be borderless to allow dragging
const DRAG_REQUIRE_ALWAYS_ON_TOP = true; // require that a window be always on top to allow dragging
const DRAG_BOTTOM_DEADZONE = 0; // Leave a deadzone of 'n' pixels from the bottom of the window going upwards.
// Usually used for being able to slide the progress bar of the video without dragging
// If 'DRAG_REQUIRE_ALT' is false
const RESIZE_ENABLED = true; // enable window resizing with CTRL + SHIFT + CLICK
const RESIZE_REQUIRE_BORDERLESS = false; // Require windows to be borderless to be resized
const RESIZE_REQUIRE_ALWAYS_ON_TOP = true; // Require windows to be always on top to be resized
// hotkeyPressed returns true of the specified combination is pressed
// combination should be an array of key constants.
function hotkeyPressed(combination, state) {
let n = 0;
for (let i = 0; i < combination.length; i++)
if (state[combination[i]])
n++;
return n == combination.length;
}
if (!robot.Window.isAxEnabled()) {
console.log("windows not enabled");
return
}
let listeners = [
{
name: "ALWAYS_ON_TOP",
keys: [robot.KEY_CONTROL, robot.KEY_SHIFT, robot.KEY_SPACE],
fn: toggleAlwaysOnTop,
},
{
name: "BORDERLESS",
keys: [robot.KEY_CONTROL, robot.KEY_SHIFT, robot.KEY_DOWN],
fn: toggleBorderless,
},
]
let dragOffset = [0, 0];
let dragStart = [0, 0];
let dragStartOffset = [0, 0];
let dragEnabled = false;
let canDrag = false;
// drag allows you to drag always on top windows with middle click
function drag() {
let window = robot.Window.getActive();
if (
(DRAG_REQUIRE_BORDERLESS && !window.isBorderless()) ||
(DRAG_REQUIRE_ALWAYS_ON_TOP && !window.isTopMost()) ||
(DRAG_REQUIRE_ALT && !robot.Keyboard.getState(robot.KEY_ALT)) ||
(RESIZE_ENABLED && robot.Keyboard.getState(robot.KEY_SHIFT)) // Do not move while resizing
) {
return;
}
let state = robot.Mouse.getState();
if (!dragEnabled) {
if (state[DRAG_BUTTON]) {
let wpos = window.getBounds();
let mpos = robot.Mouse.getPos();
if (mpos.y >= wpos.y + wpos.h - DRAG_BOTTOM_DEADZONE) {
return
}
dragStart = [mpos.x, mpos.y];
if (DRAG_TELEPORT_MOUSE) {
dragStartOffset = [mpos.x - wpos.x, mpos.y - wpos.y];
dragOffset = [wpos.w / 2, wpos.h - 10];
} else {
dragOffset = [mpos.x - wpos.x, mpos.y - wpos.y];
}
dragEnabled = true;
}
} else {
let mpos = robot.Mouse.getPos();
let wpos = window.getBounds();
if (!state[DRAG_BUTTON]) {
dragEnabled = false;
canDrag = false;
if (DRAG_TELEPORT_MOUSE) {
robot.Mouse.setPos(wpos.x + dragStartOffset[0], wpos.y + dragStartOffset[1]);
}
return;
}
if (!canDrag) {
let distance = Math.sqrt(Math.pow(mpos.x - dragStart[0], 2) + Math.pow(mpos.y - dragStart[1], 2));
if (distance > DRAG_SENSITIVITY && robot.Mouse.getState(DRAG_BUTTON)) {
console.log("[+] DRAG: " + distance + " > " + DRAG_SENSITIVITY + " : " + window.getTitle());
if (DRAG_TELEPORT_MOUSE) {
robot.Mouse.setPos(wpos.x + dragOffset[0], wpos.y + dragOffset[1]);
mpos.x = wpos.x + dragOffset[0];
mpos.y = wpos.y + dragOffset[1];
robot.Timer.sleep(50);
}
canDrag = true;
}
}
if (canDrag) {
window.setBounds(mpos.x - dragOffset[0], mpos.y - dragOffset[1], wpos.w, wpos.h);
}
}
}
function toggleAlwaysOnTop() {
let window = robot.Window.getActive();
if (!window.isTopMost()) {
console.log("[+] always on top: " + window.getTitle());
window.setTopMost(true);
} else {
console.log("[-] always on top: " + window.getTitle());
window.setTopMost(false);
}
}
function toggleBorderless() {
let window = robot.Window.getActive();
if (!window.isBorderless()) {
console.log("[+] borderless: " + window.getTitle());
window.setBorderless(true);
} else {
console.log("[-] borderless: " + window.getTitle());
window.setBorderless(false);
}
}
let resizeEnabled = false;
let resizeStart;
let resizeWindowSize;
let resizeSide = -1;
const RESIZE_LEFT = 0;
const RESIZE_TOP = 1;
const RESIZE_RIGHT = 2;
const RESIZE_BOTTOM = 3;
// resize a window by clicking and dragging.
// the side nearest to the cursor will be scaled
function resize() {
let state = robot.Keyboard.getState();
let window = robot.Window.getActive();
if (
(RESIZE_REQUIRE_ALWAYS_ON_TOP && !window.isTopMost()) ||
(RESIZE_REQUIRE_BORDERLESS && !window.isBorderless)
) {
return;
}
if (!resizeEnabled) {
if (hotkeyPressed([robot.KEY_CONTROL, robot.KEY_SHIFT], state) && robot.Mouse.getState(DRAG_BUTTON)) {
let wpos = window.getBounds();
let mpos = robot.Mouse.getPos();
if (
(RESIZE_REQUIRE_BORDERLESS && !window.isBorderless()) ||
(RESIZE_REQUIRE_ALWAYS_ON_TOP && !window.isTopMost())
) {
return;
}
resizeStart = mpos;
resizeWindowSize = wpos;
resizeEnabled = true;
console.log("[+] RESIZE: " + window.getTitle());
}
} else {
if (!(hotkeyPressed([robot.KEY_CONTROL, robot.KEY_SHIFT], state) && robot.Mouse.getState(DRAG_BUTTON))) {
resizeEnabled = false;
resizeSide = -1;
return;
}
// let window = robot.Window.getActive();
let mpos = robot.Mouse.getPos();
if (resizeSide == -1) {
let wpos = window.getBounds();
// distances of cursor from sides
let left = mpos.x - wpos.x;
let right = wpos.x + wpos.w - mpos.x;
let top = mpos.y - wpos.y;
let bottom = wpos.y + wpos.h - mpos.y;
if (left < right && left < top && left < bottom) { // left
resizeSide = RESIZE_LEFT;
} else if (right < left && right < top && right < bottom) { // right
resizeSide = RESIZE_RIGHT;
} else if (top < left && top < right && top < bottom) { // top
resizeSide = RESIZE_TOP;
} else if (bottom < left && bottom < right && bottom < top) { // bottom
resizeSide = RESIZE_BOTTOM;
}
}
switch (resizeSide) {
case RESIZE_LEFT:
window.setBounds(resizeWindowSize.x + (mpos.x - resizeStart.x), resizeWindowSize.y, resizeWindowSize.w - (mpos.x - resizeStart.x), resizeWindowSize.h);
break;
case RESIZE_RIGHT:
window.setBounds(resizeWindowSize.x, resizeWindowSize.y, resizeWindowSize.w + (mpos.x - resizeStart.x), resizeWindowSize.h);
break;
case RESIZE_BOTTOM:
window.setBounds(resizeWindowSize.x, resizeWindowSize.y, resizeWindowSize.w, resizeWindowSize.h + (mpos.y - resizeStart.y));
break;
case RESIZE_TOP:
window.setBounds(resizeWindowSize.x, resizeWindowSize.y + (mpos.y - resizeStart.y), resizeWindowSize.w, resizeWindowSize.h - (mpos.y - resizeStart.y));
}
}
}
while (true) {
for (l of listeners) {
let state = robot.Keyboard.getState();
if (typeof l.enabled === "undefined") {
l.enabled = false;
}
if (l.keys) {
if (!l.enabled) {
if (hotkeyPressed(l.keys, state)) {
l.fn();
l.enabled = true;
}
} else {
if (!hotkeyPressed(l.keys, state)) {
l.enabled = false;
}
}
}
}
if (DRAG_ENABLED) {
drag();
}
if (RESIZE_ENABLED) {
resize();
}
robot.Timer.sleep(5);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment