mirror of
https://github.com/gosticks/PaperWM.git
synced 2026-08-16 22:20:28 +00:00
282 lines
9.1 KiB
JavaScript
282 lines
9.1 KiB
JavaScript
Clutter = imports.gi.Clutter;
|
|
Tweener = imports.ui.tweener;
|
|
Lang = imports.lang;
|
|
St = imports.gi.St;
|
|
Workspace = imports.ui.workspace;
|
|
|
|
calcOffset = function(metaWindow) {
|
|
let buffer = metaWindow.get_buffer_rect();
|
|
let frame = metaWindow.get_frame_rect();
|
|
let x_offset = frame.x - buffer.x;
|
|
let y_offset = frame.y - buffer.y;
|
|
return [x_offset, y_offset];
|
|
}
|
|
|
|
allocationChanged = function allocationChanged(actor, propertySpec) {
|
|
this.layout(this.clones);
|
|
}
|
|
|
|
const notifySignal = Symbol();
|
|
|
|
WindowCloneLayout = new Lang.Class({
|
|
Name: 'PaperWindowCloneLayout',
|
|
Extends: Clutter.LayoutManager,
|
|
|
|
_init: function() {
|
|
this.parent();
|
|
},
|
|
|
|
_makeBoxForWindow: function(window) {
|
|
// We need to adjust the position of the actor because of the
|
|
// consequences of invisible borders -- in reality, the texture
|
|
// has an extra set of "padding" around it that we need to trim
|
|
// down.
|
|
|
|
// The outer rect (from which we compute the bounding box)
|
|
// paradoxically is the smaller rectangle, containing the positions
|
|
// of the visible frame. The input rect contains everything,
|
|
// including the invisible border padding.
|
|
let inputRect = window.get_buffer_rect();
|
|
let frame = window.get_frame_rect();
|
|
|
|
let box = new Clutter.ActorBox();
|
|
|
|
box.set_origin((inputRect.x - frame.x),
|
|
(inputRect.y - frame.y));
|
|
box.set_size(inputRect.width, inputRect.height);
|
|
|
|
return box;
|
|
},
|
|
|
|
vfunc_get_preferred_height: function(container, forWidth) {
|
|
let frame = container.get_first_child().meta_window.get_frame_rect();
|
|
return [frame.height, frame.height];
|
|
},
|
|
|
|
vfunc_get_preferred_width: function(container, forHeight) {
|
|
let frame = container.get_first_child().meta_window.get_frame_rect();
|
|
return [frame.width, frame.width];
|
|
},
|
|
|
|
vfunc_allocate: function(container, box, flags) {
|
|
container.get_children().forEach(Lang.bind(this, function (child) {
|
|
let realWindow;
|
|
// if (child == container._delegate._windowClone)
|
|
// realWindow = container._delegate.realWindow;
|
|
// else
|
|
realWindow = child.source;
|
|
|
|
child.allocate(this._makeBoxForWindow(realWindow.meta_window),
|
|
flags);
|
|
}));
|
|
}
|
|
});
|
|
|
|
function Minimap(space) {
|
|
let viewport = new Clutter.Actor();
|
|
viewport.space = space;
|
|
|
|
function updateClones() {
|
|
viewport.clones = space.map((mw) => {
|
|
let windowActor = mw.get_compositor_private()
|
|
let clone = new Clutter.Clone({ source: windowActor });
|
|
let container = new St.Widget({ layout_manager: new WindowCloneLayout() });
|
|
clone.meta_window = mw;
|
|
if (windowActor[notifySignal]) {
|
|
windowActor.disconnect(windowActor[notifySignal]);
|
|
}
|
|
windowActor[notifySignal] = windowActor.connect("notify::allocation",
|
|
Lang.bind(viewport, dynamic_function_ref("allocationChanged")));
|
|
|
|
container.add_actor(clone);
|
|
// let [x_offset, y_offset] = calcOffset(clone.meta_window);
|
|
// clone.set_position(-x_offset, -y_offset);
|
|
return container;
|
|
});
|
|
|
|
}
|
|
|
|
let minimapActor = new Clutter.Actor();
|
|
|
|
viewport.restack = function (around) {
|
|
minimapActor.remove_all_children();
|
|
let clones = viewport.clones;
|
|
|
|
for (let i=0; i < around; i++) {
|
|
minimapActor.add_actor(clones[i]);
|
|
}
|
|
for (let i=clones.length-1; i>around; i--) {
|
|
minimapActor.add_actor(clones[i]);
|
|
}
|
|
minimapActor.add_actor(clones[around]);
|
|
};
|
|
|
|
viewport.fold = function (around, animate = true) {
|
|
around = around || space.indexOf(space.selectedWindow);
|
|
if (around < 0) {
|
|
return;
|
|
}
|
|
|
|
let time = 0;
|
|
if (animate) {
|
|
time = 0.25;
|
|
}
|
|
|
|
this.restack(around);
|
|
let clones = viewport.clones;
|
|
|
|
let maxProtrusion = 500;
|
|
for (let i=0; i < around; i++) {
|
|
let clone = clones[i];
|
|
clone.set_pivot_point(0, 0.5);
|
|
if (clone.x + minimapActor.x <= -maxProtrusion) {
|
|
Tweener.addTween(clone, {x: -minimapActor.x - maxProtrusion
|
|
, scale_x: 0.9
|
|
, scale_y: 0.9
|
|
, transition: "easeInOutQuad"
|
|
, time: time});
|
|
}
|
|
}
|
|
for (let i=clones.length-1; i>around; i--) {
|
|
let clone = clones[i];
|
|
clone.set_pivot_point(1, 0.5);
|
|
if (clone.x + clone.width + minimapActor.x >= primary.width + maxProtrusion) {
|
|
Tweener.addTween(clone, {x: -minimapActor.x + primary.width + maxProtrusion - clone.width
|
|
, scale_x: 0.9
|
|
, scale_y: 0.9
|
|
, transition: "easeInOutQuad"
|
|
, time: time});
|
|
}
|
|
}
|
|
}
|
|
|
|
viewport.unfold = function (animate = true) {
|
|
viewport.layout(viewport.clones, animate);
|
|
}
|
|
|
|
viewport.toggle = function() {
|
|
if (!viewport.visible) {
|
|
viewport.refresh();
|
|
}
|
|
viewport.visible = !viewport.visible;
|
|
}
|
|
|
|
viewport.refresh = function() {
|
|
updateClones();
|
|
let selectedIndex = space.selectedIndex();
|
|
if(selectedIndex > -1) {
|
|
viewport.restack(selectedIndex);
|
|
viewport.layout(viewport.clones, false);
|
|
}
|
|
}
|
|
|
|
viewport.layout = function(actors, animate = true) {
|
|
function tweenTo(actor, x) {
|
|
// let [dx, dy] = calcOffset(actor.meta_window);
|
|
// actor.set_pivot_point(0, 0);
|
|
let time = 0;
|
|
if (animate) {
|
|
time = 0.25;
|
|
}
|
|
Tweener.addTween(actor, { x: x
|
|
, scale_x: 1
|
|
, scale_y: 1
|
|
, time: time
|
|
, transition: "easeInOutQuad"});
|
|
}
|
|
|
|
function propagate_forward(i, leftEdge, gap) {
|
|
if(i < 0 || i >= actors.length)
|
|
return;
|
|
let actor = actors[i];
|
|
let w = actor.width;
|
|
let x = leftEdge;
|
|
|
|
tweenTo(actor, x);
|
|
|
|
propagate_forward(i+1, x + w + gap, gap);
|
|
}
|
|
|
|
propagate_forward(0, 0, window_gap);
|
|
}
|
|
|
|
viewport.sync = function(originX) {
|
|
Tweener.addTween(minimapActor, { x: originX, time: 0.25, transition: 'easeInOutQuad' });
|
|
}
|
|
|
|
viewport.clones = [];
|
|
viewport.set_scale(0.1, 0.1);
|
|
viewport.height = primary.height;
|
|
viewport.width = primary.width;
|
|
viewport.add_actor(minimapActor);
|
|
viewport.set_background_color(Clutter.Color.get_static(3))
|
|
|
|
return viewport;
|
|
}
|
|
|
|
|
|
MultiMap = function() {
|
|
let viewport = new St.Widget();
|
|
let multimap = new St.BoxLayout()
|
|
viewport.add_actor(multimap);
|
|
multimap.set_vertical(true)
|
|
multimap.remove_all_children()
|
|
let minimaps = [];
|
|
spaces.forEach((s) => {
|
|
let wrapper = new St.Widget();
|
|
s.minimap.reparent(wrapper);
|
|
multimap.add_child(wrapper);
|
|
s.minimap.visible = true;
|
|
s.minimap.refresh();
|
|
s.minimap.fold(undefined, false);
|
|
wrapper.width = s.minimap.width * s.minimap.scale_x;
|
|
wrapper.height = s.minimap.height * s.minimap.scale_y;
|
|
minimaps.push(s.minimap);
|
|
})
|
|
let rowHeight = multimap.first_child.height;
|
|
viewport.height = rowHeight;
|
|
viewport.selectedIndex = global.screen.get_active_workspace_index();
|
|
viewport.setSelected = function(i, animate = true) {
|
|
if (i >= multimap.get_children().length ||
|
|
i < 0) {
|
|
return;
|
|
}
|
|
if (i !== viewport.selectedIndex) {
|
|
minimaps[viewport.selectedIndex].fold(undefined, animate);
|
|
}
|
|
|
|
viewport.selectedIndex = i;
|
|
let time = 0;
|
|
if (animate)
|
|
time = 0.25;
|
|
Tweener.addTween(multimap, { y: -i*rowHeight, time: time, transition: 'linear' });
|
|
minimaps[viewport.selectedIndex].unfold(animate);
|
|
}
|
|
viewport.onlyShowSelected = function() {
|
|
multimap.get_children().forEach((wrapper, i) => {
|
|
if (i !== viewport.selectedIndex) {
|
|
wrapper.hide();
|
|
}
|
|
});
|
|
multimap.y = 0;
|
|
}
|
|
viewport.showAll = function() {
|
|
multimap.get_children().forEach((wrapper, i) => {
|
|
wrapper.show();
|
|
});
|
|
viewport.setSelected(viewport.selectedIndex, false);
|
|
};
|
|
viewport.setSelected(viewport.selectedIndex, false);
|
|
let chrome = new St.Widget();
|
|
viewport.add_child(chrome);
|
|
chrome.set_size(viewport.width + 2*4, viewport.height + 2*4);
|
|
chrome.set_position(-4, -4);
|
|
chrome.set_style('border: 4px blue; border-radius: 8px;');
|
|
return viewport;
|
|
}
|
|
|
|
// bg=Main.layoutManager._backgroundGroup.get_children()[0]
|
|
// bgc= new Clutter.Clone({source:bg})
|
|
|
|
|