From 75e66de7829d0f4ec1adf5aa9932f2df66fc2dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Tue, 8 Jan 2019 20:49:23 +0100 Subject: [PATCH] keybind: super-t take window and place at final destination This also fixes the rather strange behavior of super-ctrl-above_tab which actually didn't move to the previous workspace. --- README.md | 3 +- keybindings.js | 2 + prefs.js | 2 +- schemas/gschemas.compiled | Bin 4212 -> 4260 bytes ....shell.extensions.org-scrollwm.gschema.xml | 5 + tiling.js | 111 ++++++++++-------- 6 files changed, 75 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 2604384..a9087e7 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,12 @@ PaperWM doesn't handle attached modal dialogs very well, so it's best to turn it | SuperCtrl, or SuperCtrl. | Move the current window to the left or right | | SuperCtrlLeft or SuperCtrlRight | Move the current window to the left or right | | SuperCtrlUp or SuperCtrlDown | Move the current window up or down | +| Supert | Take the window, placing it when finished navigating | | SuperTab or AltTab | Cycle through the most recently used windows | | SuperShiftTab or AltShiftTab | Cycle backwards through the most recently used windows | | SuperC | Center the active window horizontally | | SuperR | Resize the window (cycles through useful widths) | -| SuperShiftR | Resize the window (cycles through useful heights) | +| SuperShiftR | Resize the window (cycles through useful heights) | | SuperF | Maximize the width of a window | | SuperShiftF | Toggle fullscreen | | SuperReturn or SuperN | Create a new window from the active application | diff --git a/keybindings.js b/keybindings.js index d80d3f8..8ba4a40 100644 --- a/keybindings.js +++ b/keybindings.js @@ -80,6 +80,8 @@ function init() { registerNavigatorAction('move-previous-workspace-backward', Tiling.movePreviousSpaceBackwards); + registerNavigatorAction('take-window', Tiling.takeWindow); + registerMinimapAction("switch-next", (mw, space) => space.switchLinear(1)); registerMinimapAction("switch-previous", (mw, space) => space.switchLinear(-1)); diff --git a/prefs.js b/prefs.js index 7fffc6d..5acc0b1 100644 --- a/prefs.js +++ b/prefs.js @@ -165,7 +165,7 @@ class SettingsWidget { 'move-left', 'move-right', 'move-up', 'move-down', 'slurp-in', 'barf-out', 'center-horizontally', 'paper-toggle-fullscreen', 'toggle-maximize-width', 'cycle-width', - 'cycle-height'] + 'cycle-height', 'take-window'] .forEach(k => { addKeybinding(windows.model.child_model, settings, k); }); diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index 2fb3064f6697c28f7e037ad70bd29efa64c76e3b..ffff2cbe1a59529c38e75a4c7bb464ab1af80884 100644 GIT binary patch literal 4260 zcmb7HYiu0V8NJXraUR5ueTyiK@2Z55j5tBc)OskP4_o;vuT^oI5l7 zXg~=g9i4B_+`0F=-@V^=@7{8kYU`@$3jb*b|ID*P4Ze0I_)EYtAJ<>l^Ji*o7Z$t4 z-@vnYId$m5f2hx`65=}O$HAdBLNsg;;sTzRb~V${Ez=2)s|C%z`;PGK+DuY6)4G{; zIF<-qE6MYpbKsno`&a=c;HFp&Tm`@df#K?ap+$fe*a6nVCRzbZQEc?V7=9VJ8n_0a z53juW+z8{xIIR}bVh+3r9DQj)>a?jJ1D^yYk9az5>aT>PSg_lG^E*X`I&Jzt34Rjz!O4lk)M>XsKL$Pn7}xJv zqE4IsoCALX3|-xMhB|HPjg3NV0#yCgZ&9b+1ic453_SMx=MCz#xh~`2DPZ%Bf6P;- z%{Y|7-vtgd{8Y}D_FCu*;NJj$c;n1Dwx_)b`Vx5gO60`D&&d5ioBg+gZvfspb?`m5 zr%gQpz6JR0cUoVfPMiKuf=%GO(K$t(_A2OQ@L^!;=H?#iv>Tx>fR6&sd*`-Nr@aCC zY4BO#YunF*QBYHwSSMS_JjGOGon!7Yhnd%KQG5l!_LH?Cs1uv<8>LO=I8sE` z3+DeOpbcQXU=6zh;KQ1+4%h;)W_%T3&A_sY0*ja8TG_0jDVd^SI4N7xOuVVgXTZtn z8Fxnp{c=)yYg$tgMo$H;QJrESlX8i)J?h?HA2%Ic_Q6 zy}w#CyRjm^BXC0H(irNDW(VVpIw?5ouS-fZT{xbzZ2f-AbXCKc3EHKQlyub4;izi3 zimN7T=W{21dg~*nQn0mY-6}dt$+Gu5To->Gy?G5LG2bbEQzwtBS#3(rxh-4`OR-QJ zHyM|Gh1$4XJeZQib||TKx*G2Z8ShIEkFGaIs)NftdeQhPE1y>@zI$EQYtl`*sn>V* z%kD1rvNnDfMWh;wb=S%7{iMn0c5Pnl#_3s~H@2S5A#wb`?v=l;s_h|gL=GRc^St-k zx$6FEg8BWp{`#l2Y0a<-ilezo*07SQ;hoDtKew8WX1o4=s^55Z<9Q3=@4nX02~f>4 z2K^6s!T#)UVeQ&GYo{tRs%~7lySzG+nn@u&OL|)7l|N70pQraSr+L9d7r{pL#<%_b zXKE$C6b13t+@f8{VpFVb^ZYT2c0tim0{nLRXXI1ubc1&Oe3>d<9Z0HnMzM;n-;d?@ zBeTw5dO6|1U%3(e>Kka@9R5#~4ZZEs+BG1(_SY}3mi4@Te>GMd!0#*LkMHl!V!_w3 z6su$(m%igkcSF3Z@nL;son;MXjV5rEV;B#t-vsM6>-ClUHa$q@y_Dxx0=yG&es!uq zoi@+!N$@v-#qIz89d+96(97TlfKNX7@yFC@uY*1Zo(DcipT3tm?PlmNfWHoBgL@Ti z-m50T4+0Nqr(4*bHtz>>;Aeo1KYZnF>a=;@zX1L#@R#wHChD}Wf&LNrzras^o=#Gy z&HG9-F0$>wqfabbqE4IlgAn*0;KLpJ4C=IbPbz?mKyZ(w&3j}S%=@}`fGSy4R#z{k zBBXbrFx$4C)^G~AO3JcLoE3bo5TRt3Wg0U|aE|Dv!p76O#&Z}eknF0S97L zp?H5Hg5N!TBYjbPH_{i2#qc{3jYqcOyWZGP0z4Gy-xlu|9euI>p21Q49vq4d4xwFS zFy6OIbPR8c$76&1u5Z^M`Wx*Tj`WX;#^&}dp`OIf-Q$z@c8=*R`A$xCP(mD@%UT*?G&6cuakYHG zP+bg#_+vR-J*66z=zDp@_}AYFzW9GHC#_}FA`X5Yty$YD;zH&@5_6Xi?~Bak;0_i12fcKS2v=f(&ny39*-y|1`##imFiVa9Iav#4!H0k#2WT?~ z9s$n-yVg8?fbD57L;D5r^T4wkUTmUHo4I`q{A*yOce~VSQ$GQI4X6)^7Y~j^pXeXs zV5-4(zeu?-|$s0UH|XUjP6A literal 4212 zcmb7HZEPIX6@AbcoH&i0#EA`okm3}tC1$tE(-yHveoX=TK!E#DI z=Mu3kN(e!F^uHBYsj(XJ+W^cfU<$ETV?87R*Tu#Q(1rV}F2L2ekFW{)wHnt!{`H*;*AltA= zfB*1~yU0`T0?&o}5&2U`J|$1R4SX504!m;WsT6tY>%kv`{0%UAb?-amsVjdVUnSmt zVvIa>+BpsR0r1`JpU22kZv}rA@;o4Od;US5`UddbR|wGyM0r4+c@Tp<4&3m`cRDzp zdMC!8gnR?&?XBNHp86{AXCSY+68yf8zDJ%q{ft3oftCMkf0?|}!B2pj23~*bokjB0 zH-Vpnd>XK~-g1UKb=o-z`8u%o`IZOBQ)fIEA-@D3x#I1o$y46~ehZT6PGHSrr`{q@ z{Yvm<$RohBFCABLqt3V;gZwSvf4Zo?i#p?T67n?gx!pTMJJk8T??Zk`ey1p^d7(2O zT9Lqefaw#Ved@G74QT-{{ku`>QPCdZqu+QW5tfT6x>`rBO#&yLB-ToO&QSdyV`!>mP&B3V$N9= z>u&8UJ<;QedK`ohC_ix-z&?l47MlUIY}FsxU%7XnC8@s2zS;?}SFQut57}SY53d2( zXW2v9Uy;^oe?eKPK8%z>oicZY&<^@}&*b{q=DhSkNB)ibc_fYgPL%{YRNDV=VRSSi zZmMh*gB=%;Dq+H~cJ>XcxY-tx%CrL`Fmw7{u6dh!sH0x1(wl}q`>Uv2#{A+uGIGe- zy6F{`j~@=<^dk-*hh}&zamaTXE9?_%EEQlBdo+Dh6o)Pi_DB zFXX9rgP(xB8Tj94zxywF>TAItge(J}6&4PVr``d64)QuU8=dK>^GwGN_#yCPxv-Ao zsdJA#2x$WwpM3RSO6BzK=S+@Zl^}c)cuPw6)~$18=L1@1&OUG zF!HYFgzXmV63g|ujy-Qgt=Mu54xY7So$vDb(sqU&#Vau*xChW~V>^XW+x7gOgcr8CI^(UZv}hXx>1*;FEv5j{f#nM`UB_oJEYP!jiv!Lh*<-WwZC zr_;C}N@bGU@ZLarbO>@ZncbGjik`uAHZd}e`;pP~$SB4oM>2!EMbEBnnM`_w?+xxA zfxYp>u4Hyxw03lFi6w@1PE1Z8ELZ1_K6p%3LF4FhDd!eso#|K=Gr%v25m@NV(RKPJ z5i2ak!0*45f0^5(6UbhRJ;g7ZK8noeVL=uUMyF_%j6hbZwi#e5#2?EMSb5WKL_e$} z#=rSY_09jK{DLf+HSC4l#Y&!ALt_iCnBND5b;_EI_HyPE>zMV-y5+^Q0c)8Yujrrh z>zhQp5evN5_%EfM$OdiS-*u!!j{lJC1(T5bfv5(kvj(Oi%fRl{zc|eC)K_496|x5W zYQyi_$x~--ABB7n7#rBGc`(|M_D-s5*Pmqxjw2Y z6ocpABp_jO@XZ+KiZ0F>^(g*3)87PS4lpWotrG5{Jy0QOSq Tpi%3{bK%=6dsQ{zea7`G4|mz3 diff --git a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml index 2be67e1..bf75cf9 100644 --- a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml +++ b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml @@ -47,6 +47,11 @@ Attach/detach the active window into the scratch layer + + t']]]> + Take the window, dropping it when finished navigating + + period']]]> Switch to the next window diff --git a/tiling.js b/tiling.js index 7d8d28d..841f13a 100644 --- a/tiling.js +++ b/tiling.js @@ -1012,7 +1012,6 @@ class Spaces extends Map { this.clickOverlays = []; this.signals = new utils.Signals(); this.stack = []; - this._moving = []; let spaceContainer = new Clutter.Actor({name: 'spaceContainer'}); spaceContainer.hide(); this.spaceContainer = spaceContainer; @@ -1386,45 +1385,24 @@ class Spaces extends Map { let newSpace = this.selectedSpace; let to = from; if (move && this.selectedSpace.selectedWindow) { - let moving = this.selectedSpace.selectedWindow; - this._moving.push(moving); - - this.selectedSpace.removeWindow(moving); - let actor = moving.get_compositor_private(); - backgroundGroup.add_actor(moving.clone); - let lowest = this._moving[this._moving.length - 2]; - lowest && backgroundGroup.set_child_below_sibling(moving.clone, lowest.clone); - let point = this.selectedSpace.cloneContainer.apply_relative_transform_to_point( - backgroundGroup, new Clutter.Vertex({x: moving.clone.x, - y: moving.clone.y})); - moving.clone.set_position(point.x, point.y); - let x = Math.round(space.monitor.x + - space.monitor.width - - (0.1*space.monitor.width*(1 +this._moving.length))); - let y = Math.round(space.monitor.y + space.monitor.height*2/3) - + 20*this._moving.length; - moving.move_frame(true, x, y); - animateWindow(moving); - Tweener.addTween(moving.clone, - {x, y, - time: prefs.animation_time, - transition - }); - } else { - if (direction === Meta.MotionDirection.DOWN) - to = from + 1; - else - to = from - 1; - if (to < 0 || to >= mru.length) { - to = from; - } - if (to === from && Tweener.getTweenCount(newSpace.actor) > 0) - return; - - newSpace = mru[to]; - this.selectedSpace = newSpace; + takeWindow(this.selectedSpace.selectedWindow, + this.selectedSpace, + {navigator: Navigator.getNavigator()}); } + if (direction === Meta.MotionDirection.DOWN) + to = from + 1; + else + to = from - 1; + if (to < 0 || to >= mru.length) { + to = from; + } + if (to === from && Tweener.getTweenCount(newSpace.actor) > 0) + return; + + newSpace = mru[to]; + this.selectedSpace = newSpace; + TopBar.updateWorkspaceIndicator(newSpace.workspace.index()); mru.forEach((space, i) => { @@ -1462,14 +1440,6 @@ class Spaces extends Map { inPreview = false; TopBar.updateWorkspaceIndicator(to.workspace.index()); - this._moving.reverse().forEach(w => { - w.change_workspace(to.workspace); - if (w.get_workspace() === to.workspace) { - insertWindow(w, {existing: true}); - } - }); - this._moving = []; - this.selectedSpace = to; to.actor.show(); @@ -2571,3 +2541,52 @@ function movePreviousSpace(mw, space) { function movePreviousSpaceBackwards(mw, space) { spaces.selectSpace(Meta.MotionDirection.UP, true); } + +/** + Detach the @metaWindow, storing it at the bottom right corner while + navigating. When done, insert all the detached windows again. + */ +function takeWindow(metaWindow, space, {navigator}) { + space = space || spaces.selectedSpace; + metaWindow = metaWindow || space.selectedWindow; + navigator = navigator || Navigator.getNavigator(); + if (!space.removeWindow(metaWindow)) + return; + + if (!navigator._movingId) { + navigator._moving = []; + let id = navigator.connect('destroy', () => { + navigator.disconnect(id); + let space = spaces.selectedSpace; + navigator._moving.reverse().forEach(w => { + w.change_workspace(space.workspace); + if (w.get_workspace() === space.workspace) { + insertWindow(w, {existing: true}); + } + }); + }); + } + + navigator._moving.push(metaWindow); + let parent = backgroundGroup; + let actor = metaWindow.get_compositor_private(); + parent.add_actor(metaWindow.clone); + let lowest = navigator._moving[navigator._moving.length - 2]; + lowest && parent.set_child_below_sibling(metaWindow.clone, lowest.clone); + let point = space.cloneContainer.apply_relative_transform_to_point( + parent, new Clutter.Vertex({x: metaWindow.clone.x, + y: metaWindow.clone.y})); + metaWindow.clone.set_position(point.x, point.y); + let x = Math.round(space.monitor.x + + space.monitor.width - + (0.1*space.monitor.width*(1 +navigator._moving.length))); + let y = Math.round(space.monitor.y + space.monitor.height*2/3) + + 20*navigator._moving.length; + metaWindow.move_frame(true, x, y); + animateWindow(metaWindow); + Tweener.addTween(metaWindow.clone, + {x, y, + time: prefs.animation_time, + transition: 'easeInOutQuad', + }); +}