awesomeWM / awesome

awesome window manager
https://awesomewm.org/
GNU General Public License v2.0
6.39k stars 597 forks source link

not show application name when it have icon ? #3232

Open v6cc opened 3 years ago

v6cc commented 3 years ago
awesome v4.3 (Too long)
 • Compiled against Lua 5.3.5 (running with Lua 5.3)
 • D-Bus support: ✔
 • execinfo support: ✔
 • xcb-randr version: 1.6
 • LGI version: 0.9.2

awesome_icon

because some application have icon, I don't want show their name , like in pic : not show Brave, qutebrowser, Mozilla Firefox
still show Issues · awesomeWM/awesome Is there a way not show application name when it have icon ?

psychon commented 3 years ago

CC @Elv13 do you have an idea how to do this? I thought "sure, this is easy", but update_callback does not have access to the "final settings" (text, icon) and writing an own label function requires too much copy&paste since the default one is not accessible.

Aire-One commented 3 years ago

I think the update_callback is the way to do. You can access the icon and text widgets through the :get_children_by_id method just as shown in the taglist widget example at https://awesomewm.org/apidoc/widgets/awful.widget.taglist.html.

Maybe use a widget_template with a stack container and play with the visible property of icon and text widgets.

psychon commented 3 years ago

@Aire-One Problem is that the update_callback is called before the code goes ahead and sets the text and icons, so you cannot overwrite something there...

Oh, but you could hide the widget!

ShayAgros commented 3 years ago

Changing the markup won't help since it is overridden after the call to update callback. Maybe tweak the visability of the textbox ? Something like this

        widget_template = {
            {
                {
                    {
                        {
                            id     = 'icon_role',
                            widget = wibox.widget.imagebox,
                        },
                        margins = 2,
                        widget  = wibox.container.margin,
                    },
                    {
                        id     = 'text_role',
                        widget = wibox.widget.textbox,
                        markup = 'here some text',
                    },
                    layout = wibox.layout.fixed.horizontal,
                },
                left  = 10,
                right = 10,
                widget = wibox.container.margin
            },
            id     = 'background_role',
            widget = wibox.container.background,

            update_callback = function(self, c, index, objects) --luacheck: no unused
                text_role = self:get_children_by_id('text_role')[1]
                if c.icon then
                    text_role:set_visible(false)
                else
                    text_role:set_visible(true)
                end
            end,
        },
    }

I'm still far from understanding the full impact of turning off the visibality but it seems to work in my tests

psychon commented 3 years ago

@ShayAgros thanks for writing exactly what I wanted to write. That way I don't have to. Yup, that should be the way to go.

Aire-One commented 3 years ago

@psychon by changing the widget_template I had more in mind something like "extra widget will not take extra space as they are stacked" but I guess it's still a false assumption anyway as visibility would already prevent such issue...

@ShayAgros thanks for your code example, it's what I had in mind :)

v6cc commented 3 years ago

Changing the markup won't help since it is overridden after the call to update callback. Maybe tweak the visability of the textbox ? Something like this

      widget_template = {
          {
              {
                  {
                      {
                          id     = 'icon_role',
                          widget = wibox.widget.imagebox,
                      },
                      margins = 2,
                      widget  = wibox.container.margin,
                  },
                  {
                      id     = 'text_role',
                      widget = wibox.widget.textbox,
                      markup = 'here some text',
                  },
                  layout = wibox.layout.fixed.horizontal,
              },
              left  = 10,
              right = 10,
              widget = wibox.container.margin
          },
          id     = 'background_role',
          widget = wibox.container.background,

          update_callback = function(self, c, index, objects) --luacheck: no unused
              text_role = self:get_children_by_id('text_role')[1]
              if c.icon then
                  text_role:set_visible(false)
              else
                  text_role:set_visible(true)
              end
          end,
      },
  }

I'm still far from understanding the full impact of turning off the visibality but it seems to work in my tests

I tried this, but I want to hide application name, change not show application name when it have icon ? · Issue #3232 · awesomeWM/awesome - qutebrowser to not show application name when it have icon ? · Issue #3232 · awesomeWM/awesome

now it just show icon ...

ShayAgros commented 3 years ago

@zdmgmail I'm not sure it is something that can be easily achieved. When running xprop on different clients it seems like the "- program name" part is encoded in the title received from the application itself. Moreover, I see that not all processes add this part (for example, while Firefox and Chrome add the name of the program at the end of the title, kitty does not). I tried to "fish out" the name of the application by looking at the spawned process name, unfortunately Chrome adds "- Google Chrome" at the end, but its process is simply called 'chrome'.

Maybe you would like to try this dumb regex. It searches for the last term of the form '-some string' and removes it from the process name. This is of course far from being fail proof, but it might work for you nonetheless.

To test it you can add this instead of the previous code

        widget_template = {
            {
                {
                    {
                        {
                            id     = 'icon_role',
                            widget = wibox.widget.imagebox,
                        },
                        margins = 2,
                        widget  = wibox.container.margin,
                    },
                    {
                        id     = 'text_role',
                        widget = wibox.widget.textbox,
                    },
                    {
                        id     = 'reduced_text_role',
                        widget = wibox.widget.textbox,
                        visible = false
                    },
                    layout = wibox.layout.fixed.horizontal,
                },
                left  = 10,
                right = 10,
                widget = wibox.container.margin
            },
            id     = 'background_role',
            widget = wibox.container.background,

            update_callback = function(self, c, index, objects)
                original_text_box = self:get_children_by_id('text_role')[1]
                new_text_box = self:get_children_by_id('reduced_text_role')[1]

                if c.icon then
                    new_text_box.markup = string.gsub(c.name, "-[^-]+$", "")
                    original_text_box:set_visible(false)
                    new_text_box:set_visible(true)
                else
                    new_text_box:set_visible(false)
                    original_text_box:set_visible(true)
                end
            end,
        },

(btw if you see any specific applications that the regex above breaks, you can "opt them out" by something like this

if string.find(c.name, "kitty") ~= nil then
    -- the if condition from above
end

again not optimal, but might do the trick

v6cc commented 3 years ago

@ShayAgros thanks, it works! But a problem is lose center text ...

losecenter

ShayAgros commented 3 years ago

@zdmgmail Yup ... The solution I gave you is problematic because it throws away all the textbox configurations that were set by the WM.

I'm proposing a more robust solution to this problem:

        widget_template = {
            {
                {
                    {
                        {
                            id     = 'icon_role',
                            widget = wibox.widget.imagebox,
                        },
                        margins = 2,
                        widget  = wibox.container.margin,
                    },
                    {
                        id     = 'text_role',
                        widget = wibox.widget.textbox,
                    },
                    layout = wibox.layout.fixed.horizontal,
                },
                left  = 10,
                right = 10,
                widget = wibox.container.margin
            },
            id     = 'background_role',
            widget = wibox.container.background,

            create_callback = function(self, c, index, objects)
                text_box = self:get_children_by_id('text_role')[1]
                oset_mark_up_silently = text_box.set_markup_silently

                text_box.set_markup_silently = function(self, text)
                    if c.icon then
                        text = string.gsub(text, "-[^-]+</span>", "</span>")
                    end
                    return oset_mark_up_silently(self, text)
                end
            end,
        },

This solution is still hackish in the sense that it might remove a pattern of the form - some text which isn't the program's name. I cannot go around this issue since I couldn't find a way to identify the program's name in this text (maybe other people here would know better). Still, I think it would provide you with better results since it doesn't override the other text from the WM.

Please let me know if this solves your issue

psychon commented 3 years ago

Cross-link: https://www.reddit.com/r/awesomewm/comments/kjv2em/way_to_change_naming_of_client_in_tasklist_widget/

psychon commented 3 years ago

I think AwesomeWM allows assigning to c.name. How about connecting to property::name and remove the suffix from there?

v6cc commented 3 years ago

@ShayAgros the new solution will keep textbox configurations ? I tried and seem same as before... lost center text

ShayAgros commented 3 years ago

I think AwesomeWM allows assigning to c.name. How about connecting to property::name and remove the suffix from there?

@psychon Changing the client name was actually my first approach. However, if I change the client's name property in update_callback, I might change the name too many times (i.e. at first change the title github page - awesome repo - Google Chrome into github page - awesome repo and then change it into github page). Without knowing the program's name I'm left with removing the last instance of - some string from the text to be displayed, which might appear several times in the name.

@zdmgmail Hi, the last code I sent only modifies the string of the title (I redefined the function which is called to set up text for it), so it shouldn't affect textbox configurations. Do you mind sending me what configurations you used so I could check please?

v6cc commented 3 years ago

@ShayAgros

center

losecenter

I just add widget_template in s.mytasklist


awful.screen.connect_for_each_screen(function(s)

....
    s.mytasklist = awful.widget.tasklist {
        screen  = s,
        filter  = awful.widget.tasklist.filter.currenttags,
        buttons = tasklist_buttons,
        style = {
            align = 'center',
            fg_normal = '#F8F8F2',
            bg_normal = '#282A36',
            -- fg_focus = '#55586A',
            bg_focus = '#4D4E60',
            shape_border_width = 1,
            shape_border_color = '#777777',
            shape  = gears.shape.rounded_bar
        },
        -- widget_template = widget_template,
        widget_template = {
            {
                {
                    {
                        {
                            id     = 'icon_role',
                            widget = wibox.widget.imagebox,
                        },
                        margins = 2,
                        widget  = wibox.container.margin,
                    },
                    {
                        id     = 'text_role',
                        widget = wibox.widget.textbox,
                    },
                    layout = wibox.layout.fixed.horizontal,
                },
                left  = 10,
                right = 10,
                widget = wibox.container.margin
            },
            id     = 'background_role',
            widget = wibox.container.background,

            create_callback = function(self, c, index, objects)
                text_box = self:get_children_by_id('text_role')[1]
                oset_mark_up_silently = text_box.set_markup_silently

                text_box.set_markup_silently = function(self, text)
                    if c.icon then
                        text = string.gsub(text, "-[^-]+</span>", "</span>")
                    end
                    return oset_mark_up_silently(self, text)
                end
            end,
        },

    }
psychon commented 3 years ago

However, if I change the client's name property in update_callback, I might change the name too many times (i.e. at first change the title github page - awesome repo - Google Chrome into github page - awesome repo and then change it into github page).

Uhm...

local ignore_me = false
client.connect_signal("property::name", function(c)
    if ignore_me or #c.icon_sizes() == 0 then return end
    ignore_me = true
    c.name = string.gsub(c.name, "-[^-]+", ") -- this does not work correctly and I do not want to mess with Lua strings right now, sorry
    ignore_me = false
end)

Also, please do not do if c.icon then. That's a memory leak.

ShayAgros commented 3 years ago

@psychon The signal suggested here is triggered even when the name wasn't changed. Using your code (with small tweaks to make it work)

local ignore_me = false
client.connect_signal("property::name", function(c)
    if ignore_me or #c.icon_sizes == 0 then return end
    ignore_me = true
    c.name = string.gsub(c.name, "-[^-]+$", "")
    ignore_me = false
end)

The problem can be reproduced with

The property::name signal would be called several times, each time with the modified name. This way

This would be easily mended if we would know exactly what are the "unwanted" strings (given my little knowledge with X server, I'm still open for suggestions on how to retrieve the program name string if it's possible).

Also why the ignore_me variable ? This isn't multi-thread safe code anyway (this would have to be compare_and_change instruction to be so)

Also, please do not do if c.icon then. That's a memory leak.

Mind explaining why ? Looking at client.c I don't see any memory allocations. Do you refer to

    /* lua gets its own reference which it will have to destroy */
    lua_pushlightuserdata(L, cairo_surface_reference(found));

in client.c:luaA_client_get_icon ?

Lua has garbage collection afaik, would it fail to do its job in this case ? (to be clear, I think c.icon_sizes is a better approach since I'm not interested in the icon itself but rather querying its existence)

the new solution will keep textbox configurations ? I tried and seem same as before... lost center text

@zdmgmail this isn't related to the function re-definition I sent but rather to the wibox.layout.fixed.horizontal class parameters. If you change the code to

        widget_template = {
            {
                {
                    {
                        {
                            id     = 'icon_role',
                            widget = wibox.widget.imagebox,
                        },
                        margins = 2,
                        widget  = wibox.container.margin,
                    },
                    {
                        id     = 'text_role',
                        widget = wibox.widget.textbox,
                    },
                    fill_space = true,
                    layout = wibox.layout.fixed.horizontal,
                },
                left  = 10,
                right = 10,
                widget = wibox.container.margin
            },
            id     = 'background_role',
            widget = wibox.container.background,

            create_callback = function(self, c, index, objects)
                text_box = self:get_children_by_id('text_role')[1]
                oset_mark_up_silently = text_box.set_markup_silently

                text_box.set_markup_silently = function(self, text)
                    if #c.icon_sizes ~= 0 then
                        text = string.gsub(text, "-[^-]+</span>", "</span>")
                    end
                    return oset_mark_up_silently(self, text)
                end
            end,
        },

(the only change is the addition of fill_space = true property to layout.fixed.horizontal and the usage of icon_size property over icon, posting it all for the sake of completeness). To give you some context, the id names given to widgets here are not accidental, in lib/awful/widget/common.lua:custom_template these ids are searched explicitly to set them to the client's name and properties (client is the class representing the program running). Without providing widget_template the tasklist would use its default template (which is defined by default_template variable in lib/awful/widget/tasklist.lua). You can use this template for a reference to what "Awesome" searches when trying to populate client's properties in the taskbar. I remember how confused I was when tweaking tasklist module for the first time.

All I did in this solution is to modify the function which is called to change the textbox containing the client's title. The modification is to check if the requested string contains the pattern -"some string" at the end of it (if there are several such pattern it only finds the last) and if so remove it before writing it to the tasklist title. This is a rather dirty solution, if anything cleaner comes to mind, I'll update

v6cc commented 3 years ago

@ShayAgros thanks a lot, it works ! I will continue learn some lua then learn your way

psychon commented 3 years ago

This would be easily mended if we would know exactly what are the "unwanted" strings (given my little knowledge with X server, I'm still open for suggestions on how to retrieve the program name string if it's possible).

A random idea would be to add print(debug.traceback()) to the callback. I just did that and the traceback did not say anything interesting. I guess this means that it was the browser itself changing its window name on tag switch (which makes sense to me since it updates its name to show the currently selected tab). No idea why you see multiple such signals.

However, I do not understand why this still causes the callback to be applied multiple times. I'd say "add a print(new_name) and check if your string.gsub really does what you think it does" (I had the problem that the gsub itself removed everything after the first dash, hence my "I do not feel like messing with the string library above...)

Also why the ignore_me variable ? This isn't multi-thread safe code anyway (this would have to be compare_and_change instruction to be so)

The code does c.name = something. This changes the name of the client and thus the property::name signal is emitted. The ignore_me variable is there to ignore that second recursive call.

Also, please do not do if c.icon then. That's a memory leak.

Mind explaining why ? Looking at client.c I don't see any memory allocations. Do you refer to

/ lua gets its own reference which it will have to destroy / lua_pushlightuserdata(L, cairo_surface_reference(found));

Yup. That cairo_surface_reference() increases a reference count. The expectation is for Lua to decrement it again. However, lua_pushlightuserdata() deals with void*. Light user datums are just "some random pointer" without a __gc metamethod. To give it the proper type and properly consume that extra reference, you have to do gears.surface(c.icon) in Lua. That sets up the proper wrapper that frees this extra reference.

And no, I do not know how to (sanely) directly construct a LGI wrapper type for the surface from C. Hence, Lua has to do that.

ShayAgros commented 3 years ago

@psychon thanks for this explanation (: