glenreesor / HammerBar

A Windows-Like Taskbar for MacOS
GNU General Public License v3.0
17 stars 4 forks source link

Upcoming features #5

Open daveedmee opened 2 months ago

daveedmee commented 2 months ago

I have some ideas for upcoming features and if you're game for providing input, I'll close this issue and create a new one specifically for that discussion :smile:

Originally posted by @glenreesor in https://github.com/glenreesor/HammerBar/issues/2#issuecomment-2323408192

daveedmee commented 2 months ago

I'll be happy to help :)

glenreesor commented 2 months ago

Awesome.

I'd be interested in your thoughts on the following features that I'm considering -- which resonate with you, or if you have specific ideas on what they should look like.

Anyway, those are my initial thoughts :smile: . I'm curious what your thoughts are.

daveedmee commented 2 months ago

hell yea that sounds fun, okay here we go:

  • showing a window preview when hovering on a window button (we've already chatted about this, but I'm including it here for completeness)

Is there a way to get a thumbnail on popup? can we add buttons to the tooltip?

 [ Icon ] | `AppName` or custom window title | [close] [terminate] 
  thumbnail 

  • add a new type of "launcher" button which would run a user-specified lua function

    • My initial use case is toggling a debug mode where more logging goes to the console, but it could also be useful for something like starting a command line program, or a program that requires command line switches
    • for example I have different Firefox profiles, but the only way to start with a specific profile is by using the commandline)

okay so basically a more user-friendly way to add the widgets into the init.lua?

Or are we speaking in terms of creating shortcuts? Something like dragging scripts and icons into the bar to add them to it? For custom icon support we could


  • add a section to the panel that lists the currently running applications

    • this thought occurred to me since unlike Windows or Linux, closing the last window of a Mac app doesn't terminate the app
    • so perhaps a list of running apps, but still have the taskbar beside that

ooo I hate that on mac

Something like a running tasks widget would be nice. (maybe filtered out the the applications on the taskbar already)

a row of closed but not terminated icons and left click re opens them, (right click an options menu? not sure for what options though) and shift left click could terminate (or whatever extra key feels right, cmd makes sense too)


  • add the ability to customize colors

    • I noticed in your screenshots that you switched to more of a dark theme
    • A simple implementation would be just selecting "light" or "dark"
    • A more detailed implementation would include specifying all colors (background, foreground, borders)
    • Along the lines of custom colors, perhaps expose other things like font size and the spacing between text and borders of window buttons and so on

Oh yeah I prefer a darker theme for most of my stuff and my arch distro is a mix of cattpuccin mocha and custom colors. so custom themes would be nice.

I noticed that color values are declared in different kinds of styles

init.lua:

        1106
    local function render(self)
    local color = {red = 150 / 255, green = 150 / 255, blue = 150 / 255}

        899
   local borderColor = {red = 0.5, green = 0.5, blue = 0.5}
   local bgColor = state.isMinimized and ({red = 0.7, green = 0.7, blue = 0.7}) or ({red = 1, green = 1, blue = 1})

what values are allowed to store color?

black and white are constants?

    2315
    local BLACK = ____constants.BLACK

how easy is it to reference them all to an external stylesheet?

there are multiple constants.ts but some are only used for black and white, we could store all the variables inside one big constants file or if possible a css stylesheet for importing custom themes more easily some values are getting first declared inside the render functions, after the constants.ts is loaded, reference it from there

it would be nice to have all the sizes, colors and paddings in one place, for background and borders, same for the show/hide buttons and the widgets and launcher icon. it makes it easier to change values for everything at once.


Also how can I experiment and build myself? My macbook says it needs the newest Xcode to build and I can't get it bc macbook is too old to be supported, older ones won't install bc i need my icloud to restore my icloud and use their own app store. is it possible to build on linux? if so, what are the requirements?

Damn, have fun reading :D

glenreesor commented 2 months ago

This is great! Lets get discussing....

Window Preview

  • showing a window preview when hovering on a window button (we've already chatted about this, but I'm including it here for completeness)

Is there a way to get a thumbnail on popup? can we add buttons to the tooltip?

 [ Icon ] | `AppName` or custom window title | [close] [terminate] 
  thumbnail 

Ah, hadn't thought of that. If I'm understanding correctly, you're suggesting something like this from KDE desktop:

Hover with close button

Or if user doesn't want a window preview, a right-click menu:

right click menu

Launcher for User-Specified Lua Function

  • add a new type of "launcher" button which would run a user-specified lua function

    • My initial use case is toggling a debug mode where more logging goes to the console, but it could also be useful for something like starting a command line program, or a program that requires command line switches
    • for example I have different Firefox profiles, but the only way to start with a specific profile is by using the commandline)

okay so basically a more user-friendly way to add the widgets into the init.lua?

Or are we speaking in terms of creating shortcuts? Something like dragging scripts and icons into the bar to add them to it? For custom icon support we could

* store a custom alias and pinpoint the user to that to use mac tools to customize it (that alias could then store the run arguments)

* store a svg (or whatever works best, maybe even allow multiple formats?) inside a custom folder (maybe something like
  `~/.hammerspoon/hammerbar `or `~/.config/hammerbar`)

Oh, I didn't describe this very well :smile:, although your second question (about dragging scripts and icons onto the bar) is closer to what I had in mind.

To take my example of starting firefox with a different profile (for example I have a profile I use for dev work that has no plugins installed), the code the user would put in init.lua would look something like this:

function startFirefox()
  luaRun('/Applications/Firefox/.app/Contents/MacOS/firefox -P developerProfile')  -- Not sure the lua-way to do this off hand :-)
end

spoon.HammerBar:addScriptLauncher({
  iconPath = '~/myIcons/Firefox.png',
  myFunction = startFirefox
})

So now there'd be an icon on the taskbar to start Firefox using a different user profile.

What you suggested above I think would be neat, but I think ideally it would be part of a graphical way to configure all of HammerBar, although that would be a pretty big undertaking, so not something I'm thinking of in the short term.

List of Running Applications

  • add a section to the panel that lists the currently running applications

    • this thought occurred to me since unlike Windows or Linux, closing the last window of a Mac app doesn't terminate the app
    • so perhaps a list of running apps, but still have the taskbar beside that

ooo I hate that on mac

Me too!

Something like a running tasks widget would be nice. (maybe filtered out the the applications on the taskbar already)

a row of closed but not terminated icons and left click re opens them, (right click an options menu? not sure for what options though) and shift left click could terminate (or whatever extra key feels right, cmd makes sense too)

I wonder if having a list of closed but not terminated icons would be confusing for the user, as opposed to just listing all running apps (although it would be a bit redundant with the current list of open windows).

As for how to interact with it, if we're interested in creating a Windows / Linux style taskbar, I think a right-click menu would be the way to go. Although as you point out, what would the options be?? Could also just have an "X" icon top right of the app icon that would close it.

Custom Colors

  • add the ability to customize colors

    • I noticed in your screenshots that you switched to more of a dark theme
    • A simple implementation would be just selecting "light" or "dark"
    • A more detailed implementation would include specifying all colors (background, foreground, borders)
    • Along the lines of custom colors, perhaps expose other things like font size and the spacing between text and borders of window buttons and so on

Oh yeah I prefer a darker theme for most of my stuff and my arch distro is a mix of cattpuccin mocha and custom colors. so custom themes would be nice.

I used to prefer dark themes, but my eyes have gotten worse and light is the only way I can comfortably read small text :rofl: .

I noticed that color values are declared in different kinds of styles

init.lua:

        1106
    local function render(self)
    local color = {red = 150 / 255, green = 150 / 255, blue = 150 / 255}

        899
   local borderColor = {red = 0.5, green = 0.5, blue = 0.5}
   local bgColor = state.isMinimized and ({red = 0.7, green = 0.7, blue = 0.7}) or ({red = 1, green = 1, blue = 1})

what values are allowed to store color?

black and white are constants?

What you're seeing is the result of transpiling Typescript code, which is why a lot of things look weird :smile:. Black and white are indeed constants, but ones that I declared in src/constants.ts. The way to define a color for HammerSpoon is the red/green/blue format you quoted above:

myColor = { red = [some number], green = [some number], blue = [some number]}

Looks like somewhere I had decided using fractions was good so I could easily compare colors, but then just switched to straight decimals. Purely a personal preference and both are equivalent.

    2315
    local BLACK = ____constants.BLACK

how easy is it to reference them all to an external stylesheet?

there are multiple constants.ts but some are only used for black and white, we could store all the variables inside one big constants file or if possible a css stylesheet for importing custom themes more easily some values are getting first declared inside the render functions, after the constants.ts is loaded, reference it from there

it would be nice to have all the sizes, colors and paddings in one place, for background and borders, same for the show/hide buttons and the widgets and launcher icon. it makes it easier to change values for everything at once.

Ah you know CSS! Cool. I was thinking a bit in terms of CSS-like things (padding, margin, border radius, etc) although Hammerspoon doesn't do CSS so all of these would have to be implemented manually.

Agreed that putting everything in one place is the way to go. I was thinking of providing a lua interface to make it a bit easier than modifying the HammerBar init.lua directly.

A simple implementation of light/dark would look something like this:

spoon.HammerBar.theme('[light or dark]')

Another possibility would be to define "primary" and "secondary" colors, which the panel and widget buttons then use how they like, although I'm not sure how that would play out in practice and if it would give enough control:

spoon.HammerBar.defineTheme({
  primaryForeground = { red = X, green = X, blue = X},
  primaryBackground = { red = X, green = X, blue = X},
  secondaryForeground = { red = X, green = X, blue = X},
  secondaryBackground = { red = X, green = X, blue = X},
})

So then I was thinking, perhaps just define everything:

spoon.HammerBar.defineStyle({
  panel = {
    foregroundColor = XXX,
    backgroundColor = XXX,
    borderColor = XXX,
    borderRadius = XXX,
    padding = XXX,    (Padding between border and window buttons and widgets)
  },
  windowButton = {
    foregroundColor = XXX,
    backgroundColor = XXX,
    borderColor = XXX,
    borderRadius = XXX,
    padding = XXX,    (Padding between window button border and icon / window title)
  },
  widget = {
    foregroundColor = XXX,
    backgroundColor = XXX,
    borderColor = XXX,
    borderRadius = XXX,
    padding = XXX,    (Padding between widget border and widget contents)

    -- Maybe also secondary foreground and background colors that the widget would use if required
  }
})

Also how can I experiment and build myself? My macbook says it needs the newest Xcode to build and I can't get it bc macbook is too old to be supported, older ones won't install bc i need my icloud to restore my icloud and use their own app store. is it possible to build on linux? if so, what are the requirements?

You can definitely build on Linux -- that's what I do, although given how this project builds I suspect you could also do it on Mac with any editor of your choice.

As I mentioned above, the code is compiled from typescript to lua using a tool called tstl. Here's what you need to do (I should probably put this in the README.md :smile: ):

Not sure how easy that will be, but given that you've already done some tinkering with the existing init.lua perhaps you'll be able to find your way around. If not, hit me up!

Damn, have fun reading :D

I did!

daveedmee commented 2 months ago

Window Preview

Ah, hadn't thought of that. If I'm understanding correctly, you're suggesting something like this from KDE desktop:

Ah, Plasma my love Yeah I was thinking about something like that, with an extra terminate or force close button. These could be similar to the show/hide button on the taskbar

the hammerspoon snapshotForID function seems useful for getting thumbnails


Launcher for User-Specified Lua Function

To take my example of starting firefox with a different profile (for example I have a profile I use for dev work that has no plugins installed), the code the user would put in init.lua would look something like this:

function startFirefox()
  luaRun('/Applications/Firefox/.app/Contents/MacOS/firefox -P developerProfile')  -- Not sure the lua-way to do this off hand :-)
end

spoon.HammerBar:addScriptLauncher({
  iconPath = '~/myIcons/Firefox.png',
  myFunction = startFirefox
})

So now there'd be an icon on the taskbar to start Firefox using a different user profile.

okay so what about a generic app launcher instance on the bar, which then can be configured with parameters for

As for how to interact with it, if we're interested in creating a Windows / Linux style taskbar, I think a right-click menu would be the way to go. Although as you point out, what would the options be?? Could also just have an "X" icon top right of the app icon that would close it.

Just an X icon on the top right also works, although if we are terminating the app, a shutdown icon would probably be better. It could either be a small png file or maybe we use a custom patched font for that? I was thinking about how for example workspaces can be labelled with nerdfonts in window managers like i3 or bspwm or stuff


Custom Colors

Black and white are indeed constants, but ones that I declared in src/constants.ts

Wouldn't it be possible to source all the colors from there? the panel basically has only the panelColor, which is then referenced by fillColor and strokeColor, fontSize is also referenced in the toggle button, line graph, clock and whatnot. most of them have parts of the src/constants.ts imported already.

We could remove duplicates, rename the constants, decide on how we write the colors (0-255 or decimal) and then just import needed colors. This way a user only needs to check one file instead of all of them.

A simple implementation of light/dark would look something like this:

spoon.HammerBar.theme('[light or dark]')

I see this more as a selection for a light.ts / dark.ts / theme.ts file for hammerbar

Another possibility would be to define "primary" and "secondary" colors, which the panel and widget buttons then use how they like, although I'm not sure how that would play out in practice and if it would give enough control:

spoon.HammerBar.defineTheme({
  primaryForeground = { red = X, green = X, blue = X},
  primaryBackground = { red = X, green = X, blue = X},
  secondaryForeground = { red = X, green = X, blue = X},
  secondaryBackground = { red = X, green = X, blue = X},
})

I think this implementation would leave some guess work whether the background color when hovering over an app launcher icon would be primary, secondary or something else. but then again, polybar configs look similar and I got used to them so maybe there won't be any problems there :D

So then I was thinking, perhaps just define everything:

spoon.HammerBar.defineStyle({
  panel = {
    foregroundColor = XXX,
    backgroundColor = XXX,
    borderColor = XXX,
    borderRadius = XXX,
    padding = XXX,    (Padding between border and window buttons and widgets)
  },
  windowButton = {
  ...
  },
  ...
  ...

I like how each thing has it's own section. Maybe we can do a mixture of them both?

We first declare color values at the top and below that are all the widgets and parts listed and we reference the colors we declared earlier. If someone wants to rename his secondaryBackground to backgroundHover or something they could just open the file in a text editor, select replace all and are done. Having all the color values listed above also makes it easier to change everything at once without having to go through the whole document

glenreesor commented 1 month ago

Window Preview

Ah, hadn't thought of that. If I'm understanding correctly, you're suggesting something like this from KDE desktop:

Ah, Plasma my love Yeah I was thinking about something like that, with an extra terminate or force close button. These could be similar to the show/hide button on the taskbar

the hammerspoon snapshotForID function seems useful for getting thumbnails

Cool. And yep, that's the function I was thinking of :+1: .

Launcher for User-Specified Lua Function

To take my example of starting firefox with a different profile (for example I have a profile I use for dev work that has no plugins installed), the code the user would put in init.lua would look something like this:

function startFirefox()
  luaRun('/Applications/Firefox/.app/Contents/MacOS/firefox -P developerProfile')  -- Not sure the lua-way to do this off hand :-)
end

spoon.HammerBar:addScriptLauncher({
  iconPath = '~/myIcons/Firefox.png',
  myFunction = startFirefox
})

So now there'd be an icon on the taskbar to start Firefox using a different user profile.

okay so what about a generic app launcher instance on the bar, which then can be configured with parameters for

* **program** (path to app or bundleID),
  `luaRun('/Applications/Firefox/.app/Contents/MacOS/firefox`

* **optional arguments**
  `-P developerProfile`

* **icon (iconPath), tooltip text** and whatever else
spoon.HammerBar:addScriptLauncher({
iconPath = '~/myIcons/Firefox.png',
myFunction = startFirefox
})

Now that you mention it, I think I like a combination of these two approaches, or perhaps two different scenarios:

Scenario 1: Run any MacOS executable (without any special lua code)

To use the Firefox example from above, something like this:

spoon.HammerBar:addExecutableLauncher({
  executable = '/path/to/executable',      <--- e.g. '/Applications/Firefox/app/Contents/MacOS/firefox'
  arguments = '-P developerProfile',
  iconPath = '~/myIcons/Firefox.png`,
})

This would also provide the flexibility for user to run something else, like a shell script they've created.

Scenario 2: Run a lua Function

spoon.HammerBar:addLuaFunctionLauncher({
  fn = myLuaFunction,                 <--- maybe the user wants to use lua so they can use some HammerSpoon stuff
  iconPath = '~/myIcons/Firefox.png`,
})

List of Running Applications

As for how to interact with it, if we're interested in creating a Windows / Linux style taskbar, I think a right-click menu would be the way to go. Although as you point out, what would the options be?? Could also just have an "X" icon top right of the app icon that would close it.

Just an X icon on the top right also works, although if we are terminating the app, a shutdown icon would probably be better. It could either be a small png file or maybe we use a custom patched font for that? I was thinking about how for example workspaces can be labelled with nerdfonts in window managers like i3 or bspwm or stuff

Gotcha. Could also just "draw" the shutdown icon on the HammerSpoon canvas (same as how the CPU load widget is drawing on a canvas).

Custom Colors

Black and white are indeed constants, but ones that I declared in src/constants.ts

Wouldn't it be possible to source all the colors from there? the panel basically has only the panelColor, which is then referenced by fillColor and strokeColor, fontSize is also referenced in the toggle button, line graph, clock and whatnot. most of them have parts of the src/constants.ts imported already.

We could remove duplicates, rename the constants, decide on how we write the colors (0-255 or decimal) and then just import needed colors. This way a user only needs to check one file instead of all of them.

See my comments below.

A simple implementation of light/dark would look something like this:

spoon.HammerBar.theme('[light or dark]')

I see this more as a selection for a light.ts / dark.ts / theme.ts file for hammerbar

Agreed.

Another possibility would be to define "primary" and "secondary" colors, which the panel and widget buttons then use how they like, although I'm not sure how that would play out in practice and if it would give enough control:

spoon.HammerBar.defineTheme({
  primaryForeground = { red = X, green = X, blue = X},
  primaryBackground = { red = X, green = X, blue = X},
  secondaryForeground = { red = X, green = X, blue = X},
  secondaryBackground = { red = X, green = X, blue = X},
})

I think this implementation would leave some guess work whether the background color when hovering over an app launcher icon would be primary, secondary or something else. but then again, polybar configs look similar and I got used to them so maybe there won't be any problems there :D

Thinking about this more, I don't like the above approach I suggested, and think the one below would be the way to go. See below for more comments :smile:

So then I was thinking, perhaps just define everything:

spoon.HammerBar.defineStyle({
  panel = {
    foregroundColor = XXX,
    backgroundColor = XXX,
    borderColor = XXX,
    borderRadius = XXX,
    padding = XXX,    (Padding between border and window buttons and widgets)
  },
  windowButton = {
  ...
  },
  ...
  ...

I like how each thing has it's own section. Maybe we can do a mixture of them both?

We first declare color values at the top and below that are all the widgets and parts listed and we reference the colors we declared earlier. If someone wants to rename his secondaryBackground to backgroundHover or something they could just open the file in a text editor, select replace all and are done. Having all the color values listed above also makes it easier to change everything at once without having to go through the whole document

Hmmm, I'm not following. Can you provide an example?

Of the ideas I've suggested, I'd lean towards the last one because:

You mention hover, so that would need to be list for everything as well :smile: , so something like this:

spoon.HammerBar.defineStyle({
  panel = {
    foregroundColor = XXX,
    foregroundColorHover = XXX,
    backgroundColor = XXX,
    backgroundColorHover = XXX,
    borderColor = XXX,
    borderRadius = XXX,
    padding = XXX,    (Padding between border and window buttons and widgets)
  },
  windowButton = {
  ...
  },

But now this is starting to look very verbose! Another possibility would be to start with hard-coded light and dark themes that can be selected like spoon:HammerBar.selectTheme('dark' or 'light')

Thoughts?