diff --git a/extensions/native-window-placement/extension.js b/extensions/native-window-placement/extension.js index 74006b0c..7ced09c1 100644 --- a/extensions/native-window-placement/extension.js +++ b/extensions/native-window-placement/extension.js @@ -1,3 +1,4 @@ +// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- // import just everything from workspace.js: const Clutter = imports.gi.Clutter; const Lang = imports.lang; @@ -98,15 +99,12 @@ Rect.prototype = { translate: function(dx, dy) { this.x += dx; this.y += dy; - }, - + } }; // Put your extension initialization code here function main() { - - /** * _calculateWindowTransformationsNatural: * @clones: Array of #MetaWindow @@ -117,15 +115,12 @@ function main() { * https://projects.kde.org/projects/kde/kdebase/kde-workspace/repository/revisions/master/entry/kwin/effects/presentwindows/presentwindows.cpp */ Workspace.Workspace.prototype._calculateWindowTransformationsNatural = function(clones) { - //global.log('_calculateWindowTransformationsNatural()'); - // As we are using pseudo-random movement (See "slot") we need to make sure the list // is always sorted the same way no matter which window is currently active. clones = clones.sort(function (win1, win2) { return win2.metaWindow.get_stable_sequence() - win1.metaWindow.get_stable_sequence(); }); - // 2 * 10 px gaps at the border let area = new Rect(this._x + 10, this._y + 10, this._width - 20, this._height - 20); @@ -148,7 +143,6 @@ function main() { } } - let loop_counter = 0; let overlap; do { @@ -158,12 +152,11 @@ function main() { if (i != j && rects[i].adjusted(-WINDOW_PLACEMENT_NATURAL_GAPS, -WINDOW_PLACEMENT_NATURAL_GAPS, WINDOW_PLACEMENT_NATURAL_GAPS, WINDOW_PLACEMENT_NATURAL_GAPS).overlap( rects[j].adjusted(-WINDOW_PLACEMENT_NATURAL_GAPS, -WINDOW_PLACEMENT_NATURAL_GAPS, - WINDOW_PLACEMENT_NATURAL_GAPS, WINDOW_PLACEMENT_NATURAL_GAPS))) - { + WINDOW_PLACEMENT_NATURAL_GAPS, WINDOW_PLACEMENT_NATURAL_GAPS))) { loop_counter++; overlap = true; - //! @todo: something like a Point2D would be nicer here: + // TODO: something like a Point2D would be nicer here: // Determine pushing direction let i_center = rects[i].center(); @@ -189,8 +182,7 @@ function main() { rects[j].translate(diff[0], diff[1]); - if (WINDOW_PLACEMENT_NATURAL_MORESCREEN) - { + if (WINDOW_PLACEMENT_NATURAL_MORESCREEN) { // Try to keep the bounding rect the same aspect as the screen so that more // screen real estate is utilised. We do this by splitting the screen into nine // equal sections, if the window center is in any of the corner sections pull the @@ -214,22 +206,18 @@ function main() { ySection = (directions[i] % 2 ? 2 : 0); } if (xSection == 0 && ySection == 0) { - //diff = QPoint(bounds.topLeft() - targets[w].center()); diff[0] = bounds.x - i_center[0]; diff[1] = bounds.y - i_center[1]; } if (xSection == 2 && ySection == 0) { - //diff = QPoint(bounds.topRight() - targets[w].center()); diff[0] = bounds.x + bounds.width - i_center[0]; diff[1] = bounds.y - i_center[1]; } if (xSection == 2 && ySection == 2) { - //diff = QPoint(bounds.bottomRight() - targets[w].center()); diff[0] = bounds.x + bounds.width - i_center[0]; diff[1] = bounds.y + bounds.height - i_center[1]; } if (xSection == 0 && ySection == 2) { - //diff = QPoint(bounds.bottomLeft() - targets[w].center()); diff[0] = bounds.x - i_center[0]; diff[1] = bounds.y + bounds.height - i_center[1]; } @@ -241,7 +229,6 @@ function main() { } } - // Update bounding rect bounds = bounds.union(rects[i]); bounds = bounds.union(rects[j]); @@ -250,16 +237,13 @@ function main() { } } while (overlap && loop_counter < WINDOW_PLACEMENT_NATURAL_MAX_TRANSLATIONS); - //global.log('loop finished. ( windows processed, translations needed ) = ( ' + clones.length + ', ' + loop_counter + ' )' ); - - // Work out scaling by getting the most top-left and most bottom-right window coords. // The 20's and 10's are so that the windows don't touch the edge of the screen. // Most 20's and 10's are already calculated into area now. let scale; - scale = Math.min( area.width / bounds.width, - area.height / bounds.height, - 1.0 ); + scale = Math.min(area.width / bounds.width, + area.height / bounds.height, + 1.0); // Make bounding rect fill the screen size for later steps bounds.x = bounds.x - (area.width - bounds.width * scale) / 2 - 10 / scale; @@ -272,8 +256,7 @@ function main() { rects[i].translate(-bounds.x, -bounds.y); } - //! @todo: Implement the KDE part "Try to fill the gaps by enlarging windows if they have the space" here. (If this is wanted) - + // TODO: Implement the KDE part "Try to fill the gaps by enlarging windows if they have the space" here. (If this is wanted) // rescale to workspace let scales = []; @@ -310,15 +293,13 @@ function main() { return [clones, targets]; } - - /** * positionWindows: * @flags: * INITIAL - this is the initial positioning of the windows. * ANIMATE - Indicates that we need animate changing position. */ - Workspace.Workspace.prototype.positionWindows = function(flags) { + Workspace.Workspace.prototype.positionWindows = function(flags) { if (this._repositionWindowsId > 0) { Mainloop.source_remove(this._repositionWindowsId); this._repositionWindowsId = 0; @@ -335,8 +316,7 @@ function main() { let targets = []; let scales = []; - switch (WINDOW_PLACEMENT_STRATEGY) - { + switch (WINDOW_PLACEMENT_STRATEGY) { case "natural": [clones, targets] = this._calculateWindowTransformationsNatural(clones); break; @@ -346,7 +326,7 @@ function main() { break; } - let currentWorkspace = global.screen.get_active_workspace(); + let currentWorkspace = global.screen.get_active_workspace(); let isOnCurrentWorkspace = this.metaWorkspace == null || this.metaWorkspace == currentWorkspace; for (let i = 0; i < clones.length; i++) { @@ -368,20 +348,20 @@ function main() { /* Hidden windows should fade in and grow * therefore we need to resize them now so they * can be scaled up later */ - if (initialPositioning) { - clone.actor.opacity = 0; - clone.actor.scale_x = 0; - clone.actor.scale_y = 0; - clone.actor.x = x; - clone.actor.y = y; - } + if (initialPositioning) { + clone.actor.opacity = 0; + clone.actor.scale_x = 0; + clone.actor.scale_y = 0; + clone.actor.x = x; + clone.actor.y = y; + } - // Make the window slightly transparent to indicate it's hidden - Tweener.addTween(clone.actor, - { opacity: 255, - time: Overview.ANIMATION_TIME, - transition: 'easeInQuad' - }); + // Make the window slightly transparent to indicate it's hidden + Tweener.addTween(clone.actor, + { opacity: 255, + time: Overview.ANIMATION_TIME, + transition: 'easeInQuad' + }); } Tweener.addTween(clone.actor, @@ -392,7 +372,7 @@ function main() { time: Overview.ANIMATION_TIME, transition: 'easeOutQuad', onComplete: Lang.bind(this, function() { - this._showWindowOverlay(clone, overlay, true); + this._showWindowOverlay(clone, overlay, true); }) }); } else { @@ -403,107 +383,94 @@ function main() { } } + /// position window titles on top of windows in overlay //// -/// position window titles on top of windows in overlay //// + if ( PLACE_WINDOW_CAPTIONS_ON_TOP ) { + Workspace.WindowOverlay.prototype._init = function(windowClone, parentActor) { + let metaWindow = windowClone.metaWindow; - if ( PLACE_WINDOW_CAPTIONS_ON_TOP ) { - Workspace.WindowOverlay.prototype._init = function(windowClone, parentActor) { - let metaWindow = windowClone.metaWindow; + this._windowClone = windowClone; + this._parentActor = parentActor; + this._hidden = false; - this._windowClone = windowClone; - this._parentActor = parentActor; - this._hidden = false; + let title = new St.Label({ style_class: 'window-caption', + text: metaWindow.title }); + title.clutter_text.ellipsize = Pango.EllipsizeMode.END; + title._spacing = 0; + title._overlap = 0; - let title = new St.Label({ style_class: 'window-caption', - text: metaWindow.title }); - title.clutter_text.ellipsize = Pango.EllipsizeMode.END; - title._spacing = 0; - title._overlap = 0; + this._updateCaptionId = metaWindow.connect('notify::title', Lang.bind(this, function(w) { + this.title.text = w.title; + })); - this._updateCaptionId = metaWindow.connect('notify::title', - Lang.bind(this, function(w) { - this.title.text = w.title; - })); + let button = new St.Button({ style_class: 'window-close' }); + button._overlap = 0; - let button = new St.Button({ style_class: 'window-close' }); - button._overlap = 0; + this._idleToggleCloseId = 0; + button.connect('clicked', Lang.bind(this, this._closeWindow)); - this._idleToggleCloseId = 0; - button.connect('clicked', Lang.bind(this, this._closeWindow)); + windowClone.actor.connect('destroy', Lang.bind(this, this._onDestroy)); + windowClone.actor.connect('enter-event', Lang.bind(this, this._onEnter)); + windowClone.actor.connect('leave-event', Lang.bind(this, this._onLeave)); - windowClone.actor.connect('destroy', Lang.bind(this, this._onDestroy)); - windowClone.actor.connect('enter-event', - Lang.bind(this, this._onEnter)); - windowClone.actor.connect('leave-event', - Lang.bind(this, this._onLeave)); + this._windowAddedId = 0; + windowClone.connect('zoom-start', Lang.bind(this, this.hide)); + windowClone.connect('zoom-end', Lang.bind(this, this.show)); - this._windowAddedId = 0; - windowClone.connect('zoom-start', Lang.bind(this, this.hide)); - windowClone.connect('zoom-end', Lang.bind(this, this.show)); + button.hide(); - button.hide(); + this.title = title; + this.closeButton = button; - this.title = title; - this.closeButton = button; + parentActor.add_actor(this.title); + parentActor.add_actor(this.closeButton); + title.connect('style-changed', Lang.bind(this, this._onStyleChanged)); + button.connect('style-changed', Lang.bind(this, this._onStyleChanged)); - parentActor.add_actor(this.title); - parentActor.add_actor(this.closeButton); - title.connect('style-changed', - Lang.bind(this, this._onStyleChanged)); - button.connect('style-changed', - Lang.bind(this, this._onStyleChanged)); - // force a style change if we are already on a stage - otherwise - // the signal will be emitted normally when we are added - if (parentActor.get_stage()) - this._onStyleChanged(); - }, + // force a style change if we are already on a stage - otherwise + // the signal will be emitted normally when we are added + if (parentActor.get_stage()) + this._onStyleChanged(); + }, - Workspace.WindowOverlay.prototype.chromeHeights = function () { - return [Math.max( this.closeButton.height - this.closeButton._overlap, this.title.height - this.title._overlap), - 0]; - }, + Workspace.WindowOverlay.prototype.chromeHeights = function () { + return [Math.max( this.closeButton.height - this.closeButton._overlap, this.title.height - this.title._overlap), + 0]; + }, - Workspace.WindowOverlay.prototype.updatePositions = function(cloneX, cloneY, cloneWidth, cloneHeight) { - let button = this.closeButton; - let title = this.title; + Workspace.WindowOverlay.prototype.updatePositions = function(cloneX, cloneY, cloneWidth, cloneHeight) { + let button = this.closeButton; + let title = this.title; - let buttonX; - let buttonY = cloneY - (button.height - button._overlap); - if (St.Widget.get_default_direction() == St.TextDirection.RTL) - buttonX = cloneX - (button.width - button._overlap); - else - buttonX = cloneX + (cloneWidth - button._overlap); + let buttonX; + let buttonY = cloneY - (button.height - button._overlap); + if (St.Widget.get_default_direction() == St.TextDirection.RTL) + buttonX = cloneX - (button.width - button._overlap); + else + buttonX = cloneX + (cloneWidth - button._overlap); - button.set_position(Math.floor(buttonX), Math.floor(buttonY)); + button.set_position(Math.floor(buttonX), Math.floor(buttonY)); - if (!title.fullWidth) - title.fullWidth = title.width; - title.width = Math.min(title.fullWidth, cloneWidth); + if (!title.fullWidth) + title.fullWidth = title.width; + title.width = Math.min(title.fullWidth, cloneWidth); - let titleX = cloneX + (cloneWidth - title.width) / 2; - let titleY = cloneY - title.height + title._overlap; - title.set_position(Math.floor(titleX), Math.floor(titleY)); - }, + let titleX = cloneX + (cloneWidth - title.width) / 2; + let titleY = cloneY - title.height + title._overlap; + title.set_position(Math.floor(titleX), Math.floor(titleY)); + }, - Workspace.WindowOverlay.prototype._onStyleChanged = function() { - let titleNode = this.title.get_theme_node(); - this.title._spacing = titleNode.get_length('-shell-caption-spacing'); - this.title._overlap = titleNode.get_length('-shell-caption-overlap'); + Workspace.WindowOverlay.prototype._onStyleChanged = function() { + let titleNode = this.title.get_theme_node(); + this.title._spacing = titleNode.get_length('-shell-caption-spacing'); + this.title._overlap = titleNode.get_length('-shell-caption-overlap'); - let closeNode = this.closeButton.get_theme_node(); - this.closeButton._overlap = closeNode.get_length('-shell-close-overlap'); + let closeNode = this.closeButton.get_theme_node(); + this.closeButton._overlap = closeNode.get_length('-shell-close-overlap'); - this._parentActor.queue_relayout(); + this._parentActor.queue_relayout(); + } } - -/* - injectToFunction(Workspace.WindowOverlay.prototype, '_init', function(windowClone, parentActor) { - title._overlap = 0; - }); -*/ - - } - }