Some suggestions
Added by Sae Hirak over 12 years ago
I would first like to say that I very deeply appreciate the work you have done on subtle; out of all the window managers I've tried (xmonad, awesome, wmii, and StumpWM) it is by FAR the best. It is top notch in every way: the window manager itself, the configuration, the documentation, AND the support. It's clear that you're dedicated to doing a good job, and I would gladly pay you if I had more cash to spare.
However, there are several things that I think would make subtle even better for myself, and possibly others as well, listed in the order of most important to least:
1) I want to be able to set clients to a view without giving them a tag. I understand that subtle uses so-called "strict tagging" and that's fine (even desirable), but if a user wants to hack up a Ruby script that uses "weak tagging", I think they should be able to.
I think the best way to accomplish this is to make the views
method of clients mutable, like gravity
, geometry
, etc. This would be soooo convenient and useful. For instance, on the Snippets wiki page (http://subforge.org/projects/subtle/wiki/Snippets) the "Move windows" code could be significantly simplified to this:
# Add nine C-< number> grabs (1..9).each do |i| grab "C-%d" % [ i ] do |c| views = Subtlext::View.all # Sanity check if i <= views.size c.views = [ views[i - 1] ] end end end
Same for "Current view":
# Assign tags to clients on :client_create do |c| tags = c.tags.map { |t| t.name } # Exclusive for clients with default tag only if tags.include?("default") and 1 == tags.size c.views = [ Subtlext::View.current ] end end
2) Personally, I find tiling window managers to be far superior to stacking. I want all of my windows to be tiled (not overlapping at all) except for floating windows. Because of this, the gravities system (although very cool, unique, and flexible) doesn't help me more than a good column/row system. And so, I end up using the :horz
and :vert
tiling modes a lot.
There is one major tiling mode that I really want, though, and that's :grid
, which is where the windows are given equal space in a horizontal and vertical grid. Which means if you had 8 windows, it would look like this:
############# # # # # ############# # # # # ############# # # # #########
I tried to hack up my own version in subtle.rb
, using the :client_create
event and client.geometry
to automatically place the windows in a grid, but I haven't gotten it working yet.
3) As far as I can tell, you can't style (border, padding, margin, etc.) the :tray
at all, the one where notification icons like Pidgin show up.
4) The :title
element of the panel seems to be cut off on long titles. I understand this is probably a feature, but it would be nice to be able to configure it in some way, giving it a custom cutoff length, or disable cutoff completely (showing the full title no matter what)
Perhaps the simplest way to do that would be to have a max_width
style property, though that works based on pixels rather than characters. I can see why people might want either a character limit, a pixel limit, or both, so I think both kinds of limits should be supported, though I'm not sure how to support the character limiting (another style property, maybe?)
5) I think things like xfdesktop
shouldn't be counted for whether a tag is "visible" (affected by dynamic
or not). I mention this because I want to make a view containing the default
tag dynamic, but doing so doesn't work, because xfdesktop
is assigned to the default
tag. Perhaps it shouldn't be assigned to a tag by default?
6) For matching clients/tags, I think it would be better if the string syntax "foo"
meant an exact match, equivalent to /^foo$/
If you want to use regexp matching, you can use the /.../
regexp syntax. This is good not only because it makes it clear whether it's an exact/regexp match, but it's more convenient as well:
"^foo$" -> "foo" "foo\\\\.bar\\\\d" -> /foo\\.bar\\d/
7) As far as I can tell, there's no way to set up "global defaults" for things like tags or views. For instance, if I wanted all views to be dynamic true
unless I overwrite a particular one with dynamic false
, I don't see a way to do that.
8) Is there any way to create a global :mouse_down
event? I would like to have clients focused on click because they sometimes aren't autofocused properly (though fixing the autofocus would be good, having a :mouse_down
event might prove useful for other things in the future).
9) Kind of a nitpick, but Subtlext::View
(and others) don't accept arbitrary expressions like Subtlext::View[i - 1]
, you have to use Subtlext::View[:all][i - 1]
. Is there a technical reason for this (like Ruby not allowing it)?
Replies (15)
RE: Some suggestions. - Added by Sae Hirak over 12 years ago
I also found what I believe to be bugs, and shall be posting them on the Issue tracker.
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
Hey,
thanks and also thanks for the suggestions. I will try to answer all of them with some details why I did a certain thing or not, since some of the suggestions aren't entirely new.
1) Tagging is meant to be an abstraction to placement that is no surprise to the user. When you take awesome wm for example, placement there is sometimes a mystery /annoyane to me. When you start an app, it might appear on the current 'virtual desktop' or somewhere else.
Technically your suggestion is quite possible, but I need to add random new tags for that e.g. based on the view name or add a tag automatically when you add a new view. Reusing existing tags that the view already has might have some nasty side-effects, e.g. when subtle uses a tag that forces fullscreen. Another problem is that there's a technical limit (32 in total) of the number of tags.
I will consider it.
2) Stacking was a goal here, tiling is nice but when you have e.g. more than four windows it becomes pointless. Writing tiling algorithms is quite easy, see the layout sublet for example.
Dividing the screen into equal squares is easy:
Number of columns: cols =: ceil(sqrt(n)) Number of rows : rows =: ceil(n / cols)
So it should be (untested) like:
on :tile do |v|
n = v.clients
cols = Math.sqrt(n).ceil
rows = (n / cols).ceil
# Calculate slot size
geom = Subtlext::Screen.current.geometry
slotw = (geom.width / cols).ceil
sloth = (geom.height / rows).ceil
# Counters
posx = 0
posy = 0
v.clients.each do |c|
c.geometry = [ posx, posy, slotw, sloth ]
# Adjust position
if posx + slotw >= geom.width
posx = 0
posy += sloth
else
posx += slotw
end
end
end
3) Nope, there is no styling available yet, feel free to add a feature request for that.
4) The reason for a limit here is obvious, browser WM_TITLE can be damn long if you don't apply a limit here. There is a styling option available to control the length tho, check here.
5) Uhm what exactly is xfdesktop? When a window has no tag it gets the default tag], that's how tagging works.
6) Well,subtle is written in C after all and I have to convert regexp back and forth. I might add implicit ^ and $ to strings but that requires stupid checks and reallocating of memory or buffer modifications. Is it wrong to assume smart users?
7) Is something like that really needed? I really don't feel like having a kind of base view all other views inherit values from is a good idea. I usually just use variables, when I need a definition more than once.
8) Nope, mouse events work client-wise and it is a bit messy to handle that properly. Also I wouldn't recommend to bind a grab just on one mouse key. There is currently no check if one hook triggers another so that might lead into an infinite loop.
9) There's no technical reason, I never needed it so far and no one asked before. Add a ticket and I am going to add it. (Need tickets for that for reminder anyway)
RE: Some suggestions - Added by Sae Hirak over 12 years ago
1) I'm curious, why is there a 32-tag limit?
2) Right, that's why I use multiple views (with ~4 windows per view), and use Alt+Tab and Alt+Shift+Tab to switch between views. Obviously that may not work for everyone, but it works wonderfully for me, much better than when I used stacking window managers like metacity or xfwm4.
Thank you very much for that information! I had seen the Sublets page, but was unaware of the :tile event. That looks like it'll do what I want, which is great because I think it's best to do as much as you can in Ruby.
4) Ah, thank you! I'll test that and see if it works. I agree that a limit is nice, but I have a 1600x900 monitor, so the limit seems short to me. Being able to configure it is perfect.
5) It's the Desktop daemon program thingy for Xfce. It runs in the background, displaying the desktop wallpaper. It's not actually a normal window, so it doesn't get a border or anything like that. Its type should be "Desktop", judging by http://subforge.org/projects/subtle/wiki/Clients#Stacking
As a test, I just used subtler
to remove the "default" tag from xfdesktop and it still displays my desktop wallpaper on all views, so my suggestion is to not tag clients on the desktop stacking layer with the "default" tag, since it's presumed that they're already displaying on all views anyways (due to being desktops). That way the "default" tag can work with dynamic.
As a workaround, I can assign xfdesktop to a tag, and then simply not show that tag on any view, but it'd still be nice to have it fixed properly in subtle, without needing the workaround.
6) It's not so much about smartness than about convenience, but I understand if it's technically annoying or difficult to do. It's not a big deal, since I can just add in the ^ and $ myself.
7) Well, compare these two:
set :dynamic, true view "foo", "bar" view "qux", "corge" ... view "foobar", "yes"
view "foo" do match "bar" dynamic true end view "qux" do match "corge" dynamic true end ... view "foobar" do match "yes" dynamic true end
It doesn't add new functionality, it's just a way to remove boilerplate for options that are used in a lot of different tags/views.
Thank you very much for your helpful reply.
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
1) The limit is really technical, subtle needs to do lots of tag checks and uses bit operations for that. One integer consists of 32 bits, that is the limit. Using multiple integers for more tags kind of kills the benfit.
2) You need to add a check for a certain view, otherwise that applies to all, but should be easy to adapt. And you are welcome. ;)
5) Odd, normally subtle should handle that properly or I don't understand you. Windows like that usually have the _NET_WM_WINDOW_TYPE_DESKTOP type and subtle handles that correctly. Also it is intended, that desktop type windows appear on all views.
7) Well, that is long but you might consider that:
{ "foo" => "bar", "qux" => "corge", "foobar" => "yes" }.each do |k, v|
view k do
match v
dynamic true
end
end
Keep in mind that the DSL of subtle is still ruby and you can use it in loops and conditions, too.
RE: Some suggestions - Added by Sae Hirak over 12 years ago
7) Doh! That's perfectly acceptable, thank you!
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
5) What is the problem with the default tag then?
RE: Some suggestions - Added by Sae Hirak over 12 years ago
5) Well, here's what's happening. I have a view (let's just call it "foo") that is set up to show the default tag:
view "foo" do match "default" dynamic true end
As you can see, it's also set up as dynamic
. Okay, so let's say I have a bunch of untagged clients, which of course means they get tagged with "default", and thus show up on the "foo" view. Great, works fine, no problem.
But now let's suppose I kill all those clients, so there aren't any more normal clients with the "default" tag. The problem is, dynamic
never triggers for the view "foo" because xfdesktop
is tagged with "default", so subtle thinks that there are still active clients on the "default" tag even though there aren't.
If I use subtler -c xfdesktop -U default
then it works properly. I tried setting up a tag like this:
tag "hidden" do match "xfdesktop" end
But it didn't work: now xfdesktop
is tagged with both "hidden" and "default" (is that intentional, by the way? I thought "default" was only given for untagged clients...) Basically, this problem would be completely solved if desktop clients weren't tagged with "default".
By the way, I'm using version 0.10.3008, so I don't know if it's actually a problem in the latest version... I'll be compiling the latest version later to see if it's still an issue or not.
RE: Some suggestions - Added by Sae Hirak over 12 years ago
Okay, I built 0.10.3203 and tried it out, but...
2) You said to do this:
on :tile do |v| ... end
Judging by your example, it seemed that you expected the v
argument to be the gravity that needs tiling. That would be great, except it doesn't work because the :tile
event isn't passed any arguments, so the argument v
is nil
.
In addition to that, although you can set the tiling
method of gravities, it appears you cannot get it:
Subtlext::Gravity[0].tiling
<WARNING> NoMethodError: undefined method `tiling' for foo:Subtlext::Gravity
This is necessary so I can seamlessly integrate it with the existing gravities system like this:
gravity :foo, [ 0, 0, 100, 100 ], :grid
on :tile do |g| if g.tiling == :grid ... end end
Should I file issues for those two problems?
4) Setting the width
of :clients
works, thanks! I would personally move the property to :title
and call it max_char
but that's just nitpicking...
5) This is still a problem even with the latest version. See above post for more details.
On the plus side, using the latest version, the :tile
event is triggered when closing a client (it didn't before), and some other bugs I had were also fixed, hurray!
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
2) Oh, that is really a bug. I expected that the tile hook gets a view object, looks I have forgotten that tiling works gravity-wise. ;)
Going to fix that later.
As you can see in the rdoc there is no #tiling method for Subtlext::Gravity and since you cannot set arbitrary values to #tiling= there was never a need to carry that information within the object. One problem here is that the length of string atoms is limited and that there is no more room to add another string.
4) I am aware of that, there's even a fixme in the code but I cannot move it easily into the other style, because the title style uses all values and the clients style doesn't.
5) That is no bug, desktop type windows are meant to be visible on all virtual desktops, I don't see a reason to break ICCCM compliance here?
RE: Some suggestions - Added by Sae Hirak over 12 years ago
5) Regardless of whether xfdesktop
has the "default" tag or not, it appears on all views, as it should. This means that the "default" tag is at best redundant, and at worst it actually interferes with the dynamic
mode.
In addition, you might have missed it, but I already tried giving xfdesktop
a hidden tag:
tag "hidden" do match "xfdesktop" end
But now xfdesktop
is tagged with both "default" and "hidden". That definitely seems to be a bug to me, since "default" should only be applied to untagged clients. My point is that desktop clients should appear on all views, and should not be tagged with "default".
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
5) Nope sorry, still not a bug. subtle assigns the default tags, when a client has a tag that is used for actual placement and your hidden tag is never visible, obviously.
Never thought of this, desktop type clients are sticky anyway so I can safely remove the default tag. Please add a ticket for this.
RE: Some suggestions - Added by Sae Hirak over 12 years ago
Done and done:
3) http://subforge.org/issues/291
5) http://subforge.org/issues/290
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
RE: Some suggestions - Added by Sae Hirak over 12 years ago
5) I just updated and it works! Thank you very much! (By the way, you probably already know, but subtle --version
still shows 0.10.3203
)
7) Excellent! I can definitely make use of this!
9) Yeah, I just tried it and it works. I guess it was just an issue with the stable version, so upgrading to latest fixed it.
RE: Some suggestions - Added by Christoph Kappel over 12 years ago
5) When you build subtle from the repo you have to run @rake clobber
@ once to reset the cached data including the fetched revision number.
7) and 9) Great. :)