Giter VIP home page Giter VIP logo

Comments (22)

Elv13 avatar Elv13 commented on July 18, 2024 1

Should those all become options?

The problems #1453 fix, yes, 13 commits, is that maximization was done in multiple steps (3 fully independent callbacks). Those steps each modified the geometry and were fighting each other. All the bugs it fixed, including this one, were due to the race conditions that ensued[1]. It can't be done with a separate "system" without breaking those again. The request::geometry is an unified pipeline. Otherwise the handler can't work. We both made this possible, you started the work on this. So everything going though the request:: API, yes, it should be implemented as option or as a custom handler.

For the tiled client, this is a separate pipeline and need to be handled differently. My "new" client layout system could handle this. The current one is stateless, so it's safe to just set the border_width whenever you want.

[1] Yes, the code to remove border for fullscreen/maximized client was there

from awesome.

actionless avatar actionless commented on July 18, 2024

IMO it makes sense

from awesome.

blueyed avatar blueyed commented on July 18, 2024

👍

I am doing this myself, with additional rules for maximized and fullscreen for example, and therefore it gets done in the arrange handler.
This could be done via property::fullscreen and property::maximized, too.

from awesome.

syphoxy avatar syphoxy commented on July 18, 2024

on this note, is there a patch for the maximized layout to disable borders?

from awesome.

r8b7xy avatar r8b7xy commented on July 18, 2024

This is my way to disable borders for max layout. It's based on copycat's config.

-- No border for maximized clients

client.connect_signal("focus",
  function(c)
    if c.maximized_horizontal == true and c.maximized_vertical == true then
      c.border_color = beautiful.border_normal
    else
      c.border_color = beautiful.border_focus
    end
  end)

client.connect_signal("unfocus",
  function(c) c.border_color = beautiful.border_normal
  end)

-- Arrange signal handler
for s = 1, screen.count() do screen[s]:connect_signal("arrange", 
  function ()
    local clients = awful.client.visible(s)
    local layout  = awful.layout.getname(awful.layout.get(s))

    if #clients > 0 then -- Fine grained borders and floaters control
      for _, c in pairs(clients) do -- Floaters always have borders
        if awful.client.floating.get(c) or layout == "floating" then
          c.border_width = beautiful.border_width

        -- No borders with only one visible client
        elseif #clients == 1 or layout == "max" then
          c.border_width = 0
        else
          c.border_width = beautiful.border_width
        end
      end
    end
  end)
end

from awesome.

syphoxy avatar syphoxy commented on July 18, 2024

that's really good, I think. I was thinking about making it so that any layout removes the borders with clients == 1 so this really goes above and beyond my original question and above my wishful thinking.

I vote to include this in the default awesome config as well.

from awesome.

blueyed avatar blueyed commented on July 18, 2024

My config is also based on copycat's:

-- Handle border sizes of clients.
for s = 1, screen.count() do screen[s]:connect_signal("arrange", function ()
  local clients = awful.client.visible(s)
  local layout = awful.layout.getname(awful.layout.get(s))

  for _, c in pairs(clients) do
    -- No borders with only one humanly visible client
    if c.maximized then
      -- NOTE: also handled in focus, but that does not cover maximizing from a
      -- tiled state (when the client had focus).
      c.border_width = 0
    elseif awful.client.floating.get(c) or layout == "floating" then
      c.border_width = beautiful.border_width
    elseif layout == "max" or layout == "fullscreen" then
      c.border_width = 0
    else
      local tiled = awful.client.tiled(c.screen)
      if #tiled == 1 then -- and c == tiled[1] then
        tiled[1].border_width = 0
        -- if layout ~= "max" and layout ~= "fullscreen" then
        -- XXX: SLOW!
        -- awful.client.moveresize(0, 0, 2, 0, tiled[1])
        -- end
      else
        c.border_width = beautiful.border_width
      end
    end
  end
end)
end

IIRC awesome's ewmh Lua module also handles "no border for maximized" already.

from awesome.

syphoxy avatar syphoxy commented on July 18, 2024

no border for maximized, as in the client window status maximized or maximized as in the layout called maximized?

I'm currently using master and it does neither by default.

from awesome.

alesandar avatar alesandar commented on July 18, 2024

Not really sure if this is the right place to mention it, but I experience an issue related to the aforementioned examples for borderless windows. When I turn a single full-screen window into a floating one and the borders are back - they're drawn out of my screen. I've a multihead configuration with two monitors and I can clearly see how the floating window spills out it's borders to my second monitor. However, I'm sure that the issue will also occur if a single monitor configuration is used and it's not related to my dualhead configuration. The problem doesn't occur for maximized windows, because even if they're converted into a floating windows - they couldn't be resized, because of the maximized window status. When I turn the floating window back into a single tiling one that will ocupy the full-screen - a small gap occurs on the bottom and the right, equal to the size of the removed borders. If nobody else experiences the issue, let me know and I'll provide screenshots. The problem occurs with both of the configurations provided by r8b7xy and blueyed. However, the gap could be fixed by changing the incmwfact (Mod + H/L, which shall do nothing when there's a single window, but somehow helps to recalculate the window size properly).

from awesome.

r8b7xy avatar r8b7xy commented on July 18, 2024

please check lcpz/awesome-copycats#83

from awesome.

blueyed avatar blueyed commented on July 18, 2024

I would like to create a PR for this..

Should it go to the default config or somewhere else?

For reference (I've started adding it to awful.client, which does not work because of circular dependencies, and probably also does not below there):

-- Handle border sizes of clients.
do
    local beautiful = require("beautiful")
    local layout = require("awful.layout")
    local screen = require("awful.screen")
    local timer = require("gears.timer")

    function client.automatic_border_width(c, s)
        s = s or c.screen
        local layout_name = layout.getname(layout.get(s))
        -- No borders with only one humanly visible client
        if c.marked then
            -- Handled separately.
            return
        elseif c.maximized then
            -- NOTE: also handled in focus, but that does not cover maximizing from
            -- a tiled state (when the client had focus).
            c.border_width = 0
        elseif c.floating or layout_name == "floating" then
            c.border_width = beautiful.border_width
        elseif layout_name == "max" or layout_name == "fullscreen" then
            c.border_width = 0
        else
            -- No border for a single tiled client.
            -- TODO: Needs to take into account "master_fill_policy" == "mwfact"?!
            local tiled = client.tiled(s)
            -- local c_tag = c:tags()[1]
            if #tiled == 1 then  -- and awful.tag.getproperty(c_tag) ~= 'master_fill_policy' then -- and c == tiled[1] then
                c.border_width = 0
                -- XXX: SLOW!  Not necessary anymore?!
                -- awful.client.moveresize(0, 0, 2, 0, tiled[1])
            else
                c.border_width = beautiful.border_width
            end
        end
    end

    local client_border_width_for_s = function(s)
        timer.delayed_call(function (c)
          local clients = client.visible(s)
          for _, c in pairs(clients) do
              client.automatic_border_width(c, s)
            print(c.name, c.border_width)
          end
        end)
    end
    capi.screen.connect_for_each_screen(function(s)
        screen[s]:connect_signal("arrange", client_border_width_for_s)
    end)

    local client_border_maximized = function(c)
        c.border_width = not c.maximized and beautiful.border_width or 0
    end
    capi.client.connect_signal('property::maximized', client_border_maximized)
    -- client.connect_signal('property::border_width', client_set_border_width)
end

Related:

-- Fine grained borders and floaters control {{{
local client_border_color = function (c)
    -- if awful.client.ismarked(c) then
    if c.marked then
      if c == capi.client.focus and beautiful.border_marked_focus then
        c.border_color = beautiful.border_marked_focus
      else
        c.border_color = beautiful.border_marked
      end
    elseif c == capi.client.focus then
      c.border_color = beautiful.border_focus
    else
      c.border_color = beautiful.border_normal
    end
end
client.connect_signal("focus",    client_border_color)
client.connect_signal("unfocus",  client_border_color)
client.connect_signal("marked",   client_border_color)
client.connect_signal("unmarked", client_border_color)

from awesome.

blueyed avatar blueyed commented on July 18, 2024

This needs a delayed call btw, to work around the issue mentioned above by @alesandar and @r8b7xy:

    local client_border_width_for_s = function(s)
        timer.delayed_call(function (c)
          local clients = client.visible(s)
          for _, c in pairs(clients) do
              client.automatic_border_width(c, s)
            print(c.name, c.border_width)
          end
        end)
    end

Looks like this "arrange" callback's changes (to border_width) are not handled correctly otherwise?!
When going from 2 to 1 clients, the single client will have "useless gaps" right and at the bottom.
It looks like the border is gone, but the client is not resized.
The delayed callback fixes that.

from awesome.

psychon avatar psychon commented on July 18, 2024

Seems like arrange is not supposed to cause yet another relayout:

diff --git a/lib/awful/layout/init.lua b/lib/awful/layout/init.lua
index 77b352d..e4af211 100644
--- a/lib/awful/layout/init.lua
+++ b/lib/awful/layout/init.lua
@@ -190,10 +190,10 @@ function layout.arrange(screen)
             g.y = g.y + useless_gap
             c:geometry(g)
         end
-        screen:emit_signal("arrange")
-
         arrange_lock = false
         delayed_arrange[screen] = nil
+
+        screen:emit_signal("arrange")
     end)
 end

(I bet this will cause an endless recursion loop for someone)

from awesome.

blueyed avatar blueyed commented on July 18, 2024

@psychon
Thanks! Not for me at least.. ;)
Will you create a PR for it?

from awesome.

psychon avatar psychon commented on July 18, 2024

I pass. Feel free to pick it up. That way I will not be blamed if this breaks someone's config. ;-)

from awesome.

blueyed avatar blueyed commented on July 18, 2024

@Elv13
Can you comment on #171 (comment), please?
I was about to re-open this issue, but then I could create a PR right away.

from awesome.

Elv13 avatar Elv13 commented on July 18, 2024

@blueyed What's the issue exactly, sorry if I missed something. Don't #1453 address the issue?

from awesome.

blueyed avatar blueyed commented on July 18, 2024

@Elv13
It's more about improving the default config to handle borders.

from awesome.

Elv13 avatar Elv13 commented on July 18, 2024

@blueyed But the PR add options, see https://awesomewm.org/apidoc/libraries/awful.ewmh.html, isn't that the way to go?

from awesome.

blueyed avatar blueyed commented on July 18, 2024

@Elv13
Not sure.. for me it's about special-casing/handling if there is only one tiled client, or if there is only a single client with a transient floating window etc. Should those all become options?

from awesome.

lharding avatar lharding commented on July 18, 2024

Why not do this visually? I could see it getting complicated depending on what you want to happen with gaps/padding, but there are various ways of dealing with that. From my RC file (this is inside my manage hook):

    local checkBorder = function()
        timer.start_new(0.1, function () -- setting border width during a geometry callback doesn't work??
            local geom = c.screen.geometry
            local gap = c.screen.selected_tag.gap + c.border_width

            print("called checkborder", c.x, c.y, c.width, c.height, gap)
            if  c.x <= geom.x + gap and
                c.y <= geom.y + gap and
                c.width >= geom.width - gap and
                c.height >= geom.height - gap then
                print("Setting width=0")
                c.border_width = 0
            else
                c.border_width = beautiful.border_width
            end
        end)
    end

    c:connect_signal("property::size", checkBorder)
    c:connect_signal("property::position", checkBorder)

from awesome.

actionless avatar actionless commented on July 18, 2024

i have a rule like that for border width (and a similar for unfocus):

local function on_client_focus(c)
  local t = choose_tag(c)
  local layout = t.layout
  local num_tiled = get_num_tiled(t)

  if persistent.titlebar.get() and (
    num_tiled > 1 or (
      num_tiled > 0 and t.master_fill_policy ~= 'expand'
    )
  ) then
    clog("F: tile: titlebars enabled explicitly")
    titlebar.make_titlebar(c, beautiful.actionless_titlebar_bg_focus, beautiful.titlebar_shadow_focus)
  elseif c.maximized then
    clog("F: maximized")
    titlebar.remove_border(c)
  elseif c.floating then
    clog("F: floating client")
    titlebar.make_titlebar(c, beautiful.actionless_titlebar_bg_focus, beautiful.titlebar_shadow_focus)
  elseif layout == awful.layout.suit.floating then
    clog("F: floating layout")
    titlebar.make_titlebar(c, beautiful.actionless_titlebar_bg_focus, beautiful.titlebar_shadow_focus)
  elseif num_tiled > 1 then
    clog("F: multiple tiling clients")
    c.border_width = beautiful.border_width
    titlebar.make_border(c, beautiful.actionless_titlebar_bg_focus, beautiful.titlebar_shadow_focus)
  elseif num_tiled == 1 then
    if t.master_fill_policy == 'expand' and screen.count() == 1 then
      clog("F: one tiling client: expand")
      titlebar.remove_border(c)
    else
      clog("F: one tiling client")
      c.border_width = beautiful.border_width
      titlebar.make_border(c, beautiful.actionless_titlebar_bg_focus, beautiful.titlebar_shadow_focus)
    end
  else
    clog("F: zero tiling clients -- other tag?")
    return on_client_unfocus(c)
  end

  c.border_color = beautiful.border_focus
end

and a separate rule for deciding the useless gap:

  awful.tag.object.get_gap = function(t)
    t = t or awful.screen.focused().selected_tag
    if not t then return end
    local num_tiled = get_num_tiled(t)
    if num_tiled == 1 and t.master_fill_policy == "expand" then
      return 0
    end
    return awful.tag.getproperty(t, "useless_gap") or beautiful.useless_gap or 0
  end

from awesome.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.