ssokolow / quicktile

Adds window-tiling hotkeys to any X11 desktop. (An analogue to WinSplit Revolution for people who don't want to use Compiz Grid)
https://ssokolow.com/quicktile/
GNU General Public License v2.0
869 stars 78 forks source link

Make window margin support accessible from quicktile.cfg #71

Closed m4l3z closed 1 year ago

m4l3z commented 7 years ago

Title was: Gaps between windows

Hello there,

Is it possible at this moment to use gaps (margins) with quicktile ? I really want to have an environment that can look like this for example .

Thanks

ssokolow commented 7 years ago

There's no specific setting that says margins, but you can accomplish that effect.

Internally, QuickTile works by defining (x, y, width, height) rectangles as percentages of the screen's width and height. For example, all that would be needed is to change the first top-left preset from (0, 0, 0.5, 0.5) to something like (0.05, 0.05, 0.4, 0.4) and so on and so forth.

I just woke up, but, once I'm more alert, I'll either tell you which lines to edit and how or I'll implement margin_x and margin_y options.

m4l3z commented 7 years ago

Thanks a lot for the answer. I already started experimenting with that but ended up having something quite messy, even tho I felt like being on the good direction. margin_x and margin_y options would make the tweaking much easier !

ssokolow commented 7 years ago

OK, because of the way QuickTile is architected (the layout presets get defined well before the configuration file gets read... It's way overdue for a major renovation), hooking the change up to keys in the configuration file is non-trivial, but I did implement support for magins in GravityLayout.

Just change this line in the source...

gv = GravityLayout()

...to something like this...

gv = GravityLayout(0.025, 0.01)

...and you'll get behaviour which looks similar to your example screenshot.

I'll leave this open and rename it as a reminder that the functionality still needs to be tied into the config file.

ssokolow commented 7 years ago

Oh, I noticed that there actually appear to be two layers of margins in that screenshot (Windows have margins, then the entire layout canvas has a margin, making the outer border roughly twice as wide as the inner margins).

If matching that really matters to you, let me know and I'll track down where to inject some margins on the raw desktop dimensions that are used to resolve the percentages GravityLayout spits out.

m4l3z commented 7 years ago

Ok it works really great, I'm super happy with this feature, thanks a lot ! The outter border/inner border difference isn't mandatory to me even tho it can be nice in the feature, the more you can customize the better, but so far I'm totally satisfied thanks ! Quicktile is now my official tile manager.

ConnorGriffin commented 6 years ago

I'm curious if it's possible to avoid GravityLayout applying gaps multiple times.

For example, with my current settings gvlay = GravityLayout(0.004, 0.006) on a 2560x1440 monitor, I get the following results:

Horizontal: 10px
Vertical: 8px

However, when I have a window on the left and a window on the right, I get a gap between them of 20px, and when two windows are stacked vertically I get a gap of 16px.

Is it possible to have the windows "share" the margin between them? It seems like a waste of space and looks very ugly to have a wide gap between two windows but a smaller gap around the outside area.

Examples: Outer margins: image

Inner margins (twice the size): image

ssokolow commented 6 years ago

GravityLayout is a hack that I haven't had time to redo properly and isn't smart enough to have asymmetric margins because it doesn't know whether a given edge is an inside or outside edge.

Also, having symmetric margins on GravityLayout and then adding an extra margin around the screen isn't as easy as it sounds because of how multi-monitor desktops with differently sized monitors behave.

That said, you can accomplish what you want. The thing to understand is that GravityLayout isn't actually necessary... it's just a helper for these lines which actually generate the presets:

    # TODO: Plumb GravityLayout.__init__'s arguments into the config file
    gvlay = GravityLayout()
    col_width = 1.0 / columns
    cycle_steps = tuple(round(col_width * x, 3)
                        for x in range(1, columns))

    middle_steps = (1.0,) + cycle_steps
    edge_steps = (0.5,) + cycle_steps

    positions = {
        'middle': [gvlay(width, 1, 'middle') for width in middle_steps],
    }

    for grav in ('top', 'bottom'):
        positions[grav] = [gvlay(width, 0.5, grav) for width in middle_steps]
    for grav in ('left', 'right'):
        positions[grav] = [gvlay(width, 1, grav) for width in edge_steps]
    for grav in ('top-left', 'top-right', 'bottom-left', 'bottom-right'):
        positions[grav] = [gvlay(width, 0.5, grav) for width in edge_steps]

    return positions

If you manually specify your presets, they can be anything.

A preset takes this form:

positions['left'] = [
    # Pressing multiple times cycles through this list
    (0.0, 0.0, 0.5, 1.0),  # 0% from left edge, 0% from top edge, 50% width, 100% height
    (0.0, 0.0, 1 / 3.0, 1.0),  # 0% from left edge, 0% from top edge, 1/3 width, 100% height
    (0.0, 0.0, 1 / 3.0 * 2, 1.0)  # 0% from left edge, 0% from top edge, 2/3 width, 100% height
]

GravityLayout's margin support just adds a little to the position of the left/top edge and subtracts twice that from the width/height. You'd just have to manually add and subtract the amounts necessary to get the margins you want.

oliverdowie commented 2 years ago

Hey has this been updated at all? Loving quicktile, but having gaps would be nice.

ssokolow commented 2 years ago

I was on a bit of a downward spiral over the last few years without realizing it, so no progress.

I'm currently trying to claw my way back out of the pit of backlogged tasks, so I may finally get to this in the near future, but I don't want to make any promises, because that was part of what made things so bad before.

oliverdowie commented 2 years ago

Ohh no worries! Totally understandable. Thanks for the reply!

victorodg commented 1 year ago

@ssokolow Hey! Can I help with this feature anyhow? I've been meaning to start contributing to open source code and this is a feature I'm very interested in. If you're interested, send me an email on victorodg@pm.me with some details to help me start!

ssokolow commented 1 year ago

@victorodg

At the moment, I've managed to recover things to a state where I can bump sufficiently small tasks to the front of the queue if I have sufficient reason... and an active question may be sufficient reason (i.e. I'm not going through QuickTile and triaging small TODOs because I just have so much backlogged), so I'll take a look and see how much work it would take for me to just fix this.

victorodg commented 1 year ago

I'm at your service

ssokolow commented 1 year ago

Well, the main demotivating factor for QuickTile development over the last few years has always been the incomplete test coverage and the threat of introducing a regression so if you'd be interested in helping to write more automated tests, that'd be a huge help.

EDIT: I just pushed a bunch of test cleanups/improvements that had been sitting, committed but not pushed, next to the half-finished, uncommitted work on a proper configuration dialog that I was doing in preparation for switching to a JSON-based configuration file so I can finally un-hardcode the stuff requiring hierarchically-structured configuration data.

I'll try to find time within the next few days to set up some GitHub Actions to bring CI testing up to the standard I now go for.

ssokolow commented 1 year ago

OK, I've pushed a branch named margin_config which exposes the existing support for window margins via the configuration file.

(I'm guessing it still required editing the code to use because I'd lost track of how much progress my refactorings had made along the way, so I thought it'd require a lot more work than it did.)

It seems to work fine on my end. Give it some thorough testing on your end and, if it's good for you too, I'll merge it.

(First time you run QuickTile on the new branch, it'll add MarginX_Percent = 0 and MarginY_Percent = 0 lines to your quicktile.cfg.)

victorodg commented 1 year ago

Wow!! You're actually doing it! Thanks man, you're awesome! I'll give it a try over here

victorodg commented 1 year ago

@ssokolow DUDE it works so well!!! You just solved ElementaryOS for me!

ssokolow commented 1 year ago

:)

So it's suitable for merging then?

victorodg commented 1 year ago

I want to contribute to your project. I found a little bug in it. I have to press the keystroke twice for it to work. I'll try to fix that!

ssokolow commented 1 year ago

Does it always require pressing twice or is it because the first keypress is switching it from "un-tiled but in roughly the same shape as the first tiling stop" to "tiled at the first tiling stop"?

...because I used to have it infer tiling stops from existing window shapes but that broke with things like video players which forced their aspect ratios and, thus, refused to accept the shapes requested of them closely enough to match the check.