mirror of
https://github.com/gosticks/PaperWM.git
synced 2026-08-18 15:00:23 +00:00
Tentative keybinding: <super>t Probably need some more work to be useful: Almost fully hidden windows should probably be excluded for instance. Could also utilize minimum-width per window-class, historic window size, heuristics to determine how many of the windows to tile. The name could be better since we're always tiled in some sense. "distribute", "reallocate", etc. Might be that a `tile-neighbour`[1] is better, or that a couple more resize commands would make it quick enough to allocate space more manually: - `expand-width`: increase the the width of the current window by the amount available from partially visible windows. If/when we make resize commands work in "super-mode" one could quickly reallocate space without messing up the MRU list too. - `slurp`: squeeze the fist partially visible window fully into the view port, probably stealing at least some space from the existing windows. [1] need two bindings though
127 lines
3.5 KiB
JavaScript
127 lines
3.5 KiB
JavaScript
|
||
debug_all = true; // Consider the default value in `debug_filter` to be true
|
||
debug_filter = { "#preview": false };
|
||
debug = function() {
|
||
let keyword = arguments[0];
|
||
let filter = debug_filter[keyword];
|
||
if (filter === false)
|
||
return;
|
||
if (debug_all || filter === true)
|
||
print(Array.prototype.join.call(arguments, " | "));
|
||
}
|
||
|
||
print_stacktrace = function(error) {
|
||
let trace;
|
||
if (!error) {
|
||
trace = (new Error()).stack.split("\n")
|
||
// Remove _this_ frame
|
||
trace.splice(0, 1);
|
||
} else {
|
||
trace = error.stack.split("\n");
|
||
}
|
||
// Remove some uninteresting frames
|
||
let filtered = trace.filter((frame) => {
|
||
return frame !== "wrapper@resource:///org/gnome/gjs/modules/lang.js:178"
|
||
});
|
||
let args = [...arguments];
|
||
args.splice(0, 1, "stacktrace:"+(args[0] ? args[0] : ""))
|
||
// Use non-breaking space to encode new lines (otherwise every frame is
|
||
// prefixed by timestamp)
|
||
let nl = " ";
|
||
args.push(nl+filtered.join(nl))
|
||
debug.apply(null, args);
|
||
}
|
||
|
||
framestr = (rect) => {
|
||
return "[ x:"+rect.x + ", y:" + rect.y + " w:" + rect.width + " h:"+rect.height + " ]";
|
||
}
|
||
|
||
/**
|
||
* Look up the function by name at call time. This makes it convenient to
|
||
* redefine the function without re-registering all signal handler, keybindings,
|
||
* etc. (this is like a function symbol in lisp)
|
||
*/
|
||
dynamic_function_ref = function(handler_name, owner_obj) {
|
||
owner_obj = owner_obj || window;
|
||
return function() {
|
||
owner_obj[handler_name].apply(this, arguments);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Adapts a function operating on a meta_window to a key handler
|
||
*/
|
||
as_key_handler = function(fn) {
|
||
if(typeof(fn) === "string") {
|
||
fn = dynamic_function_ref(fn);
|
||
}
|
||
return function(screen, monitor, meta_window, binding) {
|
||
return fn(meta_window);
|
||
}
|
||
}
|
||
|
||
function swap(array, i, j) {
|
||
let temp = array[i];
|
||
array[i] = array[j];
|
||
array[j] = temp;
|
||
}
|
||
function in_bounds(array, i) {
|
||
return i >= 0 && i < array.length;
|
||
}
|
||
|
||
|
||
//// Debug and development utils
|
||
|
||
setDevGlobals = function() {
|
||
// Accept the risk of this interfering with existing code for now
|
||
metaWindow = global.display.focus_window;
|
||
workspace = global.screen.get_active_workspace();
|
||
actor = metaWindow.get_compositor_private();
|
||
}
|
||
|
||
/**
|
||
* Visualize the frame and buffer bounding boxes of a meta window
|
||
*/
|
||
toggleWindowBoxes = function(metaWindow) {
|
||
metaWindow = metaWindow || global.display.focus_window;
|
||
|
||
if(metaWindow._paperDebugBoxes) {
|
||
metaWindow._paperDebugBoxes.forEach(box => {
|
||
box.destroy();
|
||
});
|
||
delete metaWindow._paperDebugBoxes;
|
||
return [];
|
||
}
|
||
|
||
let frame = metaWindow.get_frame_rect()
|
||
let inputFrame = metaWindow.get_buffer_rect()
|
||
let actor = metaWindow.get_compositor_private();
|
||
|
||
makeFrameBox = function({x, y, width, height}, color) {
|
||
let frameBox = new St.Widget();
|
||
frameBox.set_position(x, y)
|
||
frameBox.set_size(width, height)
|
||
frameBox.set_style("border: 2px" + color + " solid");
|
||
return frameBox;
|
||
}
|
||
|
||
let boxes = [];
|
||
|
||
boxes.push(makeFrameBox(frame, "red"));
|
||
boxes.push(makeFrameBox(inputFrame, "blue"));
|
||
|
||
if(inputFrame.x !== actor.x || inputFrame.y !== actor.y
|
||
|| inputFrame.width !== actor.width || inputFrame.height !== actor.height) {
|
||
boxes.push(makeFrameBox(actor, "yellow"));
|
||
}
|
||
|
||
boxes.forEach(box => global.stage.add_actor(box));
|
||
|
||
metaWindow._paperDebugBoxes = boxes;
|
||
return boxes;
|
||
}
|
||
|
||
function sum(array) {
|
||
return array.reduce((a, b) => a + b, 0);
|
||
}
|