paperwm / PaperWM

Tiled scrollable window management for Gnome Shell
GNU General Public License v3.0
3.05k stars 128 forks source link

Any way to set per wmclass preferences for default size #304

Closed markk closed 1 year ago

markk commented 4 years ago

It would be great to be able to set desired widths for new windows based on wmclass. I tried this in user.js but it had no effect.

Tiling.defwinprop({ wm_class: "Emacs", _targetWidth: 1536 });

Heights too, in case the window is vertically tiled after creation, if this is possible.

hedning commented 4 years ago

Not at the moment, but yeah, it's something we'd like to do, and should be fairly easy implement.

Due to how wayland handles resizing (starting several at the same time doesn't work) the resizing will probably need to be handled by the layout code. Eg. by adding a preferredWidth property which takes precedent here: https://github.com/paperwm/PaperWM/blob/clutter-dnd/tiling.js#L327

markk commented 4 years ago

As a rough hack, I added the below to tiling.js and it seems to work.

First I tried setting these values in user.js and using let mwprop = Settings.find_winprop(mw); but this results in JS ERROR: TypeError: mwprop is undefined

var mwprop = { preferredWidth: 1152, preferredHeight: 1421 };
if (mw.wm_class == "Emacs") {
  mwprop = { wm_class: "Emacs", preferredWidth: 1536, preferredHeight: 2132 };
} else if (mw.wm_class == "tilix") {
  mwprop = { wm_class: "tilix", preferredWidth: 1152, preferredHeight: 711 };
}

if (mwprop.preferredWidth) {
  targetWidth = mwprop.preferredWidth;
}
if (mwprop.preferredHeight) {
  targetHeight = mwprop.preferredHeight;
}
// Update targets (NB: must happen before resize request)
mw._targetWidth = targetWidth;
mw._targetHeight = targetHeight;
hedning commented 4 years ago

Right, the winprop is looked up when new windows are created: https://github.com/paperwm/PaperWM/blob/b33f2d859dc0eaced1d338e336928fa78943e32d/tiling.js#L2426-L2438

So you'll probably want something like this:

@@ -2441,6 +2450,8 @@ function insertWindow(metaWindow, {existing}) {
             if (winprop.focus) {
                 Main.activateWindow(metaWindow);
             }
+            metaWindow.preferredWidth = winprop.preferredWidth;
+            metaWindow.preferredHeight = winprop.preferredHeight;
         }

         if (addToScratch) {

And then apply the preferredWidth in eg. layoutColumnSimple:

@@ -319,6 +319,15 @@ class Space extends Array {
             let resizable = !mw.fullscreen &&
                 mw.get_maximized() !== Meta.MaximizeFlags.BOTH;

+            if (mw.preferredWidth) {
+                targetWidth = mw.preferredWidth;
+                delete mw.preferredWidth
+            }
+            if (mw.preferredHeight) {
+                targetHeight = mw.preferredHeight;
+                delete mw.preferredHeight
+            }
+
             if (resizable) {
                 const hasNewTarget = mw._targetWidth !== targetWidth || mw._targetHeight !== targetHeight;
                 const targetReached = f.width === targetWidth && f.height === targetHeight;

To correctly handle vertical tiling, getting the preferred width might be better done here (you'll still want to delete the preferredWidth property so its only applied once though):

@@ -413,9 +422,9 @@ class Space extends Array {

             let targetWidth;
             if (i === selectedIndex) {
-                targetWidth = selectedInColumn.get_frame_rect().width;
+                targetWidth = w.preferredWidth || selectedInColumn.get_frame_rect().width;
             } else {
-                targetWidth = Math.max(...column.map(w => w.get_frame_rect().width));
+                targetWidth = Math.max(...column.map(w => w.preferredWidth || w.get_frame_rect().width));
             }
             targetWidth = Math.min(targetWidth, workArea.width - 2*minimumMargin());

While heights might need some more handling if we want the whole column to take up all the available height (there's a use-case to freely resize the height though: https://github.com/paperwm/PaperWM/pull/189).

markk commented 4 years ago

Thanks, this is working well for width.

Height is a more complicated problem though... ideally we'd perhaps want the window to be created full height, but the its preferredHeight to be consulted when it is first pulled into a column. There seems to be a lot going on in layoutGrabColumn - I'll have a go at doing something in there.