Code Monkey home page Code Monkey logo

stackline's Introduction

stackline-logo

Version License: MIT

Visualize yabai window stacks on macOS. Works with yabai & hammerspoon.

Current status

Unfortunately, I've haven't been able to work on this project since Q3 2021. Initially, this was due to a scary bout of RSI-esque finger pain that entirely prevented from me from typing (really – I had to use Talon for basic computer use); The lesson I took away is that my hobbies shouldn't invovlve continuous typing (given I'm already typing all day for work).

I apologize that I won't be working on this anymore – but that doesn't mean you can't fork & carry the torch ;)

June 2021 update

2021-06-06: Fixes & cleanup (v0.1.61)

  • Fixed: offset indicators when menubar is not hidden (#80)
  • Fixed: Icons don't change when toggling showIcons (#68)
  • Fixed: Failure to parse json output from yabai that contains inf values (might fix #46)
  • Removed external dependency on jq
  • Removed shell script used to call out to yabai
  • Replaced third-party json library with hs.json
  • Refactored unnecessary object-orientation out of stackline.query
  • Cleaned up stackline.lib.utils

See changelog.

Everything below & more is in the wiki.

What is stackline & why would I want to use it?

stackline adds unobtrusive visual indicators to complement yabai's window stacking functionality.

A 'stack' enables multiple macOS windows to occupy the same screen space and behave as a single unit.

Stacks are a recent addition (June 2020) to the (excellent!) macOS tiling window manager koekeishiya/yabai. See yabai #203 for more info about yabai's stacking feature. Currently, there's no built-in UI for stacks, which makes it easy to forget about stacked windows that aren't visible or get disoriented.

Enter stackline: unobtrusive visual indicators that complement yabai window stacks.

stackline-demo

Features

  • 🚦 Window indicators show the position and window count of stacks
  • πŸ”¦ Use app icons to show apps inside stacks or slim indicators to save space
  • 🧘 Smart positioning. Indicators stay on the outside edge of the window nearest the screen edge
  • πŸ•ΉοΈ Flexible control. Control stackline via shell commands, or access the instance directly via hammerspoon.
  • πŸ–₯️ Multi-monitor support introduced in stackline v0.1.55
Icon indicators… …or minimal indicators

Quickstart

Prerequisites

See wiki for example keybindings to create and navigate between stacks.

Installation

  1. Clone the repo into ~/.hammerspoon/stackline
  2. Install the hammerspoon cli tool

1. Clone the repo into ~/.hammerspoon/stackline

# Get the repo
git clone https://github.com/AdamWagner/stackline.git ~/.hammerspoon/stackline

# Make stackline run when hammerspoon launches
cd ~/.hammerspoon
echo 'stackline = require "stackline"' >> init.lua
echo 'stackline:init()' >> init.lua

Now your ~/.hammerspoon directory should look like this:

β”œβ”€β”€ init.lua
└── stackline
  β”œβ”€β”€ conf.lua
  β”œβ”€β”€ stackline
  β”‚Β Β  β”œβ”€β”€ configmanager.lua
  β”‚Β Β  β”œβ”€β”€ query.lua
  β”‚Β Β  β”œβ”€β”€ stack.lua
  β”‚Β Β  β”œβ”€β”€ stackline.lua
  β”‚Β Β  β”œβ”€β”€ stackmanager.lua
  β”‚Β Β  └── window.lua
  └── lib
   Β Β  └── …

2. Install the hammerspoon cli tool

This is an optional step. It's required to send configuration commands to stackline from scripts, for example:

# Toggle boolean values with the hs cli
hs -c "stackline.config:toggle('appearance.showIcons')"
  1. Ensure Hammerspoon is running

  2. Open the hammerspoon console via the menu bar

  3. Type hs.ipc.cliInstall() and hit return

    If Hammerspoon is installed via Brew on Apple Silicon, hs.ipc.cliInstall("/opt/homebrew") #2930

  4. Confirm that hs is available by entering the following in your terminal (shell):

❯ which hs
/usr/local/bin/hs
Open the Hammperspoon console via the menu bar Type `hs.ipc.cliInstall()` and hit return

Usage

  • Launch yabai (or make sure it's running) (brew services start yabai)
  • Launch hammerspoon (or make sure it's running) (open -a "Hammerspoon")

Create a window stack

Now, assuming you've been issuing these commands from a terminal and also have a browser window open on the same space, make sure your terminal is positioned immediately to the left of your browser and issue the following command (or use keybindings) to create a stack:

yabai -m window --stack next

Did the terminal window expand to cover the area previously occupied by Safari? Great! At this point, you should notice two app icons at the top-left corner of your terminal window, like this:

You can toggle minimalist mode by turning the icons off:

hs -c 'stackline.config:toggle("appearance.showIcons")'

See the wiki to for details about how to do this with a key binding.

Thanks to contributors!

All are welcome. Feel free to dive in by opening an issue or submitting a PR.

@alin23 initially proposed the concept for stackline here and encouraged @AdamWagner to share the mostly-broken proof-of-concept publicly. Since then, @alin23 dramatically improved upon the initial proof-of-concept with #13, has some pretty whiz-bang functionality on deck with #17, and has been a great thought partner/reviewer.

@zweck, who, in the same thread, got the gears turning about how @alin23's idea could be implemented and also urged Adam to share his POC.

@johnallen3d for being of one the first folks to install stackline, and for identifying several mistakes & gaps in the setup instructions.

@pete-may for saving folks from frustration by fixing an out-of-date command in the readme (#48)

@AdamWagner wrote the initial proof-of-concept (POC) for stackline.

Give a ⭐️ if you think (a more fully-featured version of) stackline would be useful!

…on the shoulders of giants

Thanks to @koekeishiya without whom the wonderful yabai would not exist, and projects like this would have no reason to exist.

Similarly, thanks to @dominiklohmann, who has helped so many people make chunkwm/yabai "do the thing" they want and provides great feedback on new and proposed yabai features.

Thanks to @cmsj, @asmagill, and all of the contributors to hammerspoon for making macos APIs accessible to the rest of us!

Thanks to the creators & maintainers of the lua utility libraries underscore.lua, lume.lua, and self.lua.

License & attribution

stackline is licensed under the β†—Β MITΒ License, the same license used by yabai and hammerspoon.

MIT is a simple permissive license with conditions only requiring the preservation of copyright and license notices. Licensed works, modifications, and larger works may be distributed under different terms and without source code.

MIT Β© Adam Wagner

stackline's People

Contributors

adamwagner avatar alexpopov avatar alin23 avatar davay avatar jwoglom avatar lkubb avatar pete-may avatar shepherdjerred avatar taupiqueur avatar yaxollum avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stackline's Issues

Assets

Created just to store readme assets.

Round 1 (existing screenshots / screenrecordings as of 2020-08-22):

stackline-icon-indicators

stackline-pill-indicators-demo

stackline-logo2x

stackline-logo

stackline-github-banner@2x

stackline-github-banner

stackline-demo

JSON decoding error preventing Stackline from working...

Hello,

I just installed Stackline. I also have jq and yabai installed. I am receiving this error:

2020-09-09 17:06:39: 17:06:39 ERROR: LuaSkin: hs.task callback: ...rs/myUserName/.hammerspoon/stackline/stackline/query.lua:11: The data couldnβ€šΓ„Γ΄t be read because it isnβ€šΓ„Γ΄t in the correct format. stack traceback: [C]: in function 'hs.json.decode' ...rs/myUserName/.hammerspoon/stackline/stackline/query.lua:11: in function <...rs/myUserName/.hammerspoon/stackline/stackline/query.lua:10>

Stackline is not working. Thank you!

Late 2011, 13-inch MacBook Pro
MacOS High Sierra

Edit: removed username...

Stack indicators do not refresh when a stacked window is warped out of the stack

To reproduce

Create a stack of 3 windows on a space with at least one other window that is not in the stack.

Ensure that a stacked window is focused & execute:

yabai -m window --warp {west,east,north,south}

Note that when the stacked window is warped out of the stack, it will appear as if there are still 3 windows in the stack.

If the stack is unfocused & then re-focused, the correct amount of stack indicators (2) will be drawn just off the top-left edge of the active window, but the old set of 3 indicators are not cleaned-up!.

Stackline uses hardcoded path to yabai and jq in yabai-get-stack-idx

/bin/yabai-get-stack-idx uses a hardcoded path to jq and yabai. This is an issue on M1 Macs since Homebrew executables for ARM Macs are stored in a different location than x86 Macs.

Stackline failed to work properly on my M1 Mac Mini until this line was changed to the proper path (i.e. /opt/homebrew/bin/yabai).

/usr/local/bin/yabai -m query --windows \
| /usr/local/bin/jq --raw-output --compact-output --monochrome-output 'map({"\(.id)": .["stack-index"]}) | reduce .[] as $item ({}; . + $item)'

Documentation for setup

relates to this section: https://github.com/AdamWagner/stackline#2-install-the-hammerspoon-cli-tool

In this section of the documentation I think it could be clearer about what actions are required. When reading this it wasn't immediately clear that I needed to open the hammerspoon.app and then run the hs.cliInstall() there.

Then when figured out that I was supposed to be in Hammerspoon I was then trying to run the "which" command when this needs to be run back in the console.

I think some of this confusion is down to my introductory level knowledge of bash and never having used hammerspoon before but if other novices are looking to make use of this software they may similarly be confused.

Error message in hammerspoon console and no icons shown [/bin/dash only available on Catalina+]

I just installed this with the recommended init.lua contents and all the dependencies. My hammerspoon console keeps showing this error: "Warning: LuaSkin: hs.task:launch() Unable to launch hs.task process: launch path not accessible"

Full hammerspoon log:

2020-08-28 16:59:56: Welcome to the Hammerspoon Console!

You can run any Lua code in here.

2020-08-28 16:59:56: -- Lazy extension loading enabled
2020-08-28 16:59:56: -- Loading ~/.hammerspoon/init.lua
2020-08-28 16:59:56: -- Loading extension: settings
2020-08-28 16:59:56: org.hammerspoon.Hammerspoon
2020-08-28 16:59:56: -- Loading extension: ipc
2020-08-28 16:59:56: -- Loading extension: fnutils
2020-08-28 16:59:56: -- Loading extension: window
2020-08-28 16:59:56: -- Loading extension: uielement
2020-08-28 16:59:56: -- Loading extensions: window.filter
2020-08-28 16:59:56: -- Loading extension: timer
2020-08-28 16:59:56: -- Loading extension: spaces
2020-08-28 16:59:56: -- Loading extension: task
2020-08-28 16:59:56: 16:59:56 ** Warning: LuaSkin: hs.task:launch() Unable to launch hs.task process: launch path not accessible
2020-08-28 16:59:56: -- Done.
2020-08-28 17:00:01: 17:00:01 ** Warning: wfilter: No accessibility access to app U�bersicht Networking (no watcher pid)
2020-08-28 17:00:01: 17:00:01 ** Warning: wfilter: No accessibility access to app Discord Helper (Renderer) (no watcher pid)
2020-08-28 17:00:01: 17:00:01 ** Warning: wfilter: No accessibility access to app FirefoxCP Web Content (no watcher pid)
2020-08-28 17:00:01: 17:00:01 ** Warning: wfilter: No accessibility access to app FirefoxCP WebExtensions (no watcher pid)
2020-08-28 17:00:01: 17:00:01 ** Warning: wfilter: No accessibility access to app FirefoxCP RDD Process (no watcher pid)
2020-08-28 17:00:01: 17:00:01 ** Warning: wfilter: No accessibility access to app com.apple.hiservices-xpcservice (no watcher pid)
2020-08-28 17:00:11: 17:00:11 ** Warning: LuaSkin: hs.task:launch() Unable to launch hs.task process: launch path not accessible

Script to unstack windows

Hi,

I've recently switched from i3wm on Linux to yabai+stackline+skhd, so I'm kind of new to this. I have configured a keybinding to stack a window with the next one via:

yabai -m window --stack next

However, I can't seem to find any docs on how this can be undone i.e. how can I "unstack" windows.

ERROR: module 'stackline.stackline.core' not found:

Thanks for this project, love the concept!

I'm giving it a try, and I am getting the following error when launching Hammerspoon.

2020-08-03 10:07:53: Welcome to the Hammerspoon Console!
You can run any Lua code in here.

2020-08-03 10:07:53: -- Lazy extension loading enabled
2020-08-03 10:07:53: -- Loading ~/.hammerspoon/init.lua
2020-08-03 10:07:53: *** ERROR: ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: module 'stackline.stackline.core' not found:
	no field package.preload['stackline.stackline.core']
	no file '/Users/johna/.hammerspoon/stackline/stackline/core.lua'
	no file '/Users/johna/.hammerspoon/stackline/stackline/core/init.lua'
	no file '/Users/johna/.hammerspoon/Spoons/stackline/stackline/core.spoon/init.lua'
	no file '/usr/local/share/lua/5.3/stackline/stackline/core.lua'
	no file '/usr/local/share/lua/5.3/stackline/stackline/core/init.lua'
	no file '/usr/local/lib/lua/5.3/stackline/stackline/core.lua'
	no file '/usr/local/lib/lua/5.3/stackline/stackline/core/init.lua'
	no file './stackline/stackline/core.lua'
	no file './stackline/stackline/core/init.lua'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline/stackline/core.lua'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline/stackline/core/init.lua'
	no file '/Users/johna/.hammerspoon/stackline/stackline/core.so'
	no file '/usr/local/lib/lua/5.3/stackline/stackline/core.so'
	no file '/usr/local/lib/lua/5.3/loadall.so'
	no file './stackline/stackline/core.so'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline/stackline/core.so'
	no file '/Users/johna/.hammerspoon/stackline.so'
	no file '/usr/local/lib/lua/5.3/stackline.so'
	no file '/usr/local/lib/lua/5.3/loadall.so'
	no file './stackline.so'
	no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline.so'
stack traceback:
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:597: in function 'require'
	/Users/johna/.hammerspoon/init.lua:1: in main chunk
	[C]: in function 'xpcall'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:648: in function 'hs._coresetup.setup'
	(...tail calls...)

The only thing that I did differently when getting setup was not cloning to my ~/Downloads directory and dealing with relative paths (native MacOS version of ln does not support the -r flag). I cloned to ~/.hammerspoon/src/ instead, so my ~/.hammerspoon directory looks like this.

~/.hammerspoon
❯ exa -hla --git
Permissions Size User  Date Modified Name
lrwxr-xr-x    18 johna  3 Aug 10:07  bin -> src/stackline/bin
.rw-r--r--    35 johna  3 Aug  8:49  init.lua
drwxr-xr-x     - johna  3 Aug  8:46  Spoons
drwxr-xr-x     - johna  3 Aug  8:49  src
lrwxr-xr-x    24 johna  3 Aug 10:07  stackline -> src/stackline/stackline
lrwxr-xr-x    20 johna  3 Aug 10:07  utils -> src/stackline/utils

and my init.lua

~/.hammerspoon
❯ cat init.lua
require "stackline.stackline.core"

Probably something simple I'm missing. I am not (was not) a Hammerspoon user nor do I have Lua experience.

Stack indicators do not update when the tree is rotated or mirrored

To reproduce

Create a stack of 2 or more windows on a space with at least one other window that is not in the stack, and execute:

yabai -m space --mirror x-axis

…or:

yabai -m space --mirror y-axis

Note that, when the mirror operation completes, the windows have moved, but the stack indicators remain stationary.

Configurable + automatic indicator position relative to stack

Configuration ideas:

Indicator position relative to stack:

  1. Top/bottom
  2. Left/right
  3. Inside/outside

Indicator position offset relative to stack:

  • top offset
  • bottom offset
  • left offset
  • right offset

Values may be integers or percentages.
Values may be negative.

Options may be repeated / combined to achieve @alin23's mockup here with indicators that are centered on the edge of window and occlude a small amount of the window content.

Automagicβ„’ positioning

Automatically position indicators on the outside edge of the stack nearest the edge of the screen. This would be nice for users who use small or no window gaps and modest screen padding.

Stackline is not working [due to `jq` being installed via nix instead of homebrew]

I can't see a stackline after launching Hammerspoon and stacking windows

~/.hammerspoon:

.hammerspoon
β”œβ”€β”€ Spoons
β”œβ”€β”€ stackline
β”‚  β”œβ”€β”€ bin
β”‚  β”‚  └── yabai-get-stack-idx
β”‚  β”œβ”€β”€ lib
β”‚  β”‚  β”œβ”€β”€ debug.lua
β”‚  β”‚  β”œβ”€β”€ json.lua
β”‚  β”‚  β”œβ”€β”€ utils.lua
β”‚  β”‚  └── valid.lua
β”‚  β”œβ”€β”€ stackline
β”‚  β”‚  β”œβ”€β”€ configmanager.lua
β”‚  β”‚  β”œβ”€β”€ query.lua
β”‚  β”‚  β”œβ”€β”€ stack.lua
β”‚  β”‚  β”œβ”€β”€ stackline.lua
β”‚  β”‚  β”œβ”€β”€ stackmanager.lua
β”‚  β”‚  └── window.lua
β”‚  β”œβ”€β”€ conf.lua
β”‚  └── README.md
└── init.lua

~/.hammerspoon/init.lua:

stackline = require "stackline.stackline.stackline"
stackline:init()

Mac OS 11.2

Icons not showing

Hi!

I love this tool, but unfortunately stacks' icons are not showing.
I am on macOS Big Sur (11.2.1) and I followed your guide in the GitHub home page.

This is the error I get when I reload config in Hammerspoon and try to use stackline:

2021-04-07 19:43:52: -- Loading extension: geometry
2021-04-07 19:43:52: -- Lazy extension loading enabled
2021-04-07 19:43:52: -- Loading ~/.hammerspoon/init.lua
2021-04-07 19:43:52: -- Loading extension: logger
2021-04-07 19:43:52: 19:43:52      utils: Loading module
2021-04-07 19:43:52: -- Loading extension: fnutils
2021-04-07 19:43:52: -- Loading extension: window
2021-04-07 19:43:52: -- Loading extensions: window.filter
2021-04-07 19:43:52: -- Loading extension: timer
2021-04-07 19:43:52: -- Loading extension: eventtap
2021-04-07 19:43:52:           stackline: Loading module
2021-04-07 19:43:52:          sline.conf: Loading module
2021-04-07 19:43:52: -- Loading extension: spaces
2021-04-07 19:43:52:           stackline: starting stackline
2021-04-07 19:43:53: 



2021-04-07 19:43:53: ========================================
2021-04-07 19:43:53: T1	==========
2021-04-07 19:43:53: ========================================
2021-04-07 19:43:53: -- Loading extension: inspect
2021-04-07 19:43:53: {
  advanced = {
    maxRefreshRate = 0.3
  },
  appearance = {
    alpha = 1,
    color = {
      white = 0.9
    },
    dimmer = 2.5,
    fadeDuration = 0.2,
    iconDimmer = 1.1,
    iconPadding = 4,
    offset = {
      x = 4,
      y = 2
    },
    pillThinness = 6,
    radius = 3,
    shouldFade = true,
    showIcons = true,
    size = 32,
    vertSpacing = 1.2
  },
  features = {
    clickToFocus = true,
    dynamicLuminosity = "not_implemented",
    fzyFrameDetect = {
      enabled = true,
      fuzzFactor = 30
    },
    hsBugWorkaround = true,
    winTitles = "not_implemented"
  },
  paths = {
    getStackIdxs = "/Users/silver978/.hammerspoon/stackline/bin/yabai-get-stack-idx",
    jq = "/usr/local/bin/jq",
    yabai = "/usr/local/bin/yabai"
  }
}
2021-04-07 19:43:53: 



2021-04-07 19:43:53: ========================================
2021-04-07 19:43:53: T2	==========
2021-04-07 19:43:53: ========================================
2021-04-07 19:43:53: {}
2021-04-07 19:43:53: 19:43:53 sline.conf: Initializing configmanager…
2021-04-07 19:43:53:          sline.conf: schemaType: 0.3
2021-04-07 19:43:53:          sline.conf: schemaType: winTitles
2021-04-07 19:43:53:          sline.conf: schemaType: boolean
2021-04-07 19:43:53:          sline.conf: schemaType: dynamicLuminosity
2021-04-07 19:43:53:          sline.conf: schemaType: boolean
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: boolean
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: color
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: boolean
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: number
2021-04-07 19:43:53:          sline.conf: schemaType: boolean
2021-04-07 19:43:53:          sline.conf: schemaType: string
2021-04-07 19:43:53:          sline.conf: schemaType: string
2021-04-07 19:43:53:          sline.conf: schemaType: string
2021-04-07 19:43:53:          sline.conf: Not validating:  0.3
2021-04-07 19:43:53:          sline.conf: βœ“ Conf validated successfully
2021-04-07 19:43:53: -- Loading extension: task
2021-04-07 19:43:53:           stackline: FEAT: ClickTracker starting
2021-04-07 19:43:53: -- Done.
2021-04-07 19:43:53: -- Loading extension: json
2021-04-07 19:43:53: 19:43:53 ERROR:   LuaSkin: Error deserialising JSON: The data couldn’t be read because it isn’t in the correct format.
2021-04-07 19:43:53: 19:43:53 ERROR:   LuaSkin: hs.task callback: /Users/silver978/.hammerspoon/stackline/stackline/query.lua:77: attempt to index a nil value (field 'winStackIdxs')
stack traceback:
	/Users/silver978/.hammerspoon/stackline/stackline/query.lua:77: in function 'assignStackIndex'
	...on.app/Contents/Resources/extensions/hs/fnutils/init.lua:87: in function 'stackline.lib.utils.each'
	/Users/silver978/.hammerspoon/stackline/stackline/query.lua:92: in local 'fn'
	...on.app/Contents/Resources/extensions/hs/fnutils/init.lua:87: in function 'stackline.lib.utils.each'
	/Users/silver978/.hammerspoon/stackline/stackline/query.lua:91: in function 'stackline.stackline.query.mergeWinStackIdxs'
	/Users/silver978/.hammerspoon/stackline/stackline/query.lua:136: in function 'whenStackIdxDone'
	/Users/silver978/.hammerspoon/stackline/stackline/query.lua:13: in function </Users/silver978/.hammerspoon/stackline/stackline/query.lua:9>
2021-04-07 19:43:57: -- Loading extension: geometry

Which could be the issue?

Thanks in advance.

Icon indicators may not need to be inset in round rect on Big Sur

On Big Sur, app icons will already be in a round rect by default, so stackline probably doesn't need to inset icons in another round rect.

I assume we can detect macOS version via Hammerspoon so that icons on older versions of macOS continue to display as they do today.

Stackline sometimes missing icons

Hello,

first off, thank you for making stackline :)

I've noticed a rather curious bug, where SOME app icons are missing. Ex:

stackline-missing-icons

In this example, there are siz windows in this stack:

  • chrome
  • alacritty
  • kitty
  • alacritty (app icon missing)
  • chrome
  • kitty (app icon missing)

What's more interesting, is that if i navigate to those windows with stack.next and stack.prev selectors, the opacity of the rest of the stackline changes, as if i had moved focus away from the entire stack (ie. the indicator background for the last-focused window in the stack becomes 50% opaque, the rest transparent)

Tried with stackline ced4473 and with latest version of master from this morning

running with yabai-v3.3.0 on MacOS Catalina

Please let me know if there's any additional information I can provide. Thank you!

Consolidate lua utils & attribute sources

There are four different files with lua utils in /utils, which is completely unnecessary.

  • /utils/utils.lua
  • /utils/underscore.lua
  • /utils/table-utils.lua
  • /utils/flatten.lua

Worse, several of these are copied straight out of an active repo, without attribution!

Support for multiple stacks per monitor?

Hello,

First off, thank you for making this. it's really slick!

I've started using yabai's stacking feature and stackline recently, and I think it's great, but I've noticed a problem. If i have two stacks in a given space, the second stack has no stackline

The GIF in your project's readme makes it look like multiple stacks in a given space should work and each have their own stacklines, but i can't find anything in the documentation about it

Is this a bug, or a feature request?

Indicator color does not auto-adjust based on avg. luminosity of wallpaper to ensure legibility

This is only really an issue with the "pill"-style indicators – the "icon" style uses much more space, but is always legible regardless of the wallpaper.

The current background color for the pills is 99% white, with a 0.2 alpha when inactive and 0.99 alpha when active. This means the indicators are almost invisible against a light background.

Potential solution: determine the avg luminosity of the wallpaper and change background color to {dark color} when above a certain threshold.

Likely edge cases:

  • Gradient wallpapers that are light on top & dark on bottom (or vice versa). It may be possible to calculate the luminosity for a region of the wallpaper based on the user's indicator offset settings.
  • Dynamic wallpapers that change over time will require stackline to periodically check luminosity and update background color if needed

Icons don't change when toggling showIcons

When I toggle showIcons (both via terminal and hs console) the icons don't change. However, as soon as I move a window, or perform a similar action, the icons will update. So it seems that while the config is updated, the icons don't actually change until some update event is performed. Is this by design? If so, is there a command I can run to refresh the icons?

I saw you mention something similar here: #5, but this is closed, so not sure if it's the same issue or something else.

Thanks for the awesome tool!

Multi-monitor support

I haven't tested stackline on a multi-monitor setup, but @alin23 has reported some problems in the past.

Todo

  • Hook up external monitors & hunt for bugs
  • Fix bugs ;-)

Stack indicators do not refresh when gaps or padding change

To reproduce

Create a stack of 2 or more windows and execute:

yabai -m space --padding rel:25:25:25:25

…or:

yabai -m space --gap rel:30

Note that changing a space's padding/gaps causes windows to move, and that the windows move but the stack indicators remain stationary.

How to cycle through stack windows

I eventually could use stackline, but how to cycle through stack windows. in yabai bsp mode, I could achieve it through

yabai -m query --spaces \
       | jq -re ".[] | select(.visible == 1).index" \
       | xargs -I{} yabai -m query --windows --space {} \
       | jq -sre "add | sort_by(.display, .frame.x, .frame.y, .id) | reverse | nth(index(map(select(.focused == 1))) - 1).id" \
       | xargs -I{} yabai -m window --focus {}

Any reason not to deprecate support for ipc messages?

The pattern below is repeated throughout the documentation:

Config values can be set using the hs CLI:
hs -c "stackline.config:set('appearance.radius', 3)"
… or the ipc port:
echo ":appearance.radius:3 | hs -m stackline-config`

Both of these commands have the same effect – setting the apperance.radius to 3.

Benefit (?)

To my knowledge, the ipc port approach offers no real advantage.

The ipc port approach …

  • does not require less setup or fewer dependencies
  • does not offer more functionality
  • is not more or less flexible
  • is not easier to understand

…than the hs CLI.

The only benefit I can think of is inertia; if some folks are already used to the ipc approach, or get/set config values in their yabairc using ipc (I doubt there are any/many), then I understand that it's preferable to not have to change these.

Cost

Support for the ipc approach accounts for more than 20% of lines in configmanager.lua.

Also, since it must parse strings, it is substantially more complicated than calling stackline.config:set(…) or stackline.config:toggle(…).

The ipc approach requires registering a local port and is not idempotent. This caused stackline to crash for at least one user (before a guard was added to prevent initializing stackline more than once).

Finally, supporting 2 (similar) ways to accomplish the same thing unnecessarily complicates the documentation.


So, if there are good reasons not to deprecate support for modifying config values via ipc… I'm not aware of them.

Does anyone feel strongly that modifying stackline config values via ipc should not be deprecated?

Error while loading [stackline needs to be global variable in init.lua]

Hi, this looks awesome but I can't manage to make it works:

2020-09-01 08:48:10: ========================================
2020-09-01 08:48:10: STARTING STACKLINE	==========
2020-09-01 08:48:10: ========================================
2020-09-01 08:48:10: ********
2020-09-01 08:48:10: 08:48:10 ERROR:   LuaSkin: hs.timer callback error: .../cyril/.hammerspoon/stackline/stackline/stackmanager.lua:12: attempt to index a nil value (global 'stackline')
stack traceback:
	.../cyril/.hammerspoon/stackline/stackline/stackmanager.lua:12: in function 'stackline.stackline.stackmanager.new'
	/Users/cyril/.hammerspoon/stackline/stackline/stackline.lua:24: in function 'stackline.stackline.stackline.start'
	/Users/cyril/.hammerspoon/stackline/stackline/stackline.lua:85: in upvalue 'actionFn'
	...poon.app/Contents/Resources/extensions/hs/timer/init.lua:147: in function <...poon.app/Contents/Resources/extensions/hs/timer/init.lua:145>
2020-09-01 08:48:10: ********
2020-09-01 08:48:14: 08:48:14 ** Warning:   wfilter: No accessibility access to app Music Networking (no watcher pid)
2020-09-01 08:48:14: 08:48:14 ** Warning:   wfilter: No accessibility access to app Flotato Networking (no watcher pid)
2020-09-01 08:48:14: 08:48:14 ** Warning:   wfilter: No accessibility access to app Mail Networking (no watcher pid)
2020-09-01 08:48:15: 08:48:15 ** Warning:   wfilter: No accessibility access to app Electron Helper (Renderer) (no watcher pid)
2020-09-01 08:48:15: 08:48:15 ** Warning:   wfilter: No accessibility access to app Typora Networking (no watcher pid)
2020-09-01 08:48:25: ********
2020-09-01 08:48:25: 08:48:25 ERROR:   LuaSkin: hs.application.watcher callback: /Users/cyril/.hammerspoon/stackline/stackline/stackline.lua:38: attempt to index a nil value (field 'manager')
stack traceback:

I use yabai HEAD, without the SA installed (not sure if it's needed for stack line to work).

Let me know if you need further info.

Integrate dynamic indicator color feature into refactored Window class

@alin23 created an amazing feature that dynamically determines indicator color based on the specific luminosity of region of desktop background above which the indicator is displayed. Really impressive!

This feature was merged, and then accidentally overwritten by @AdamWagner (πŸ€¦β€β™‚οΈοΈ) as he was working on #18

#18 brought significant changes to the Window module in which the dynamic color feature was originally written. At this point, it's probably best to pluck out the dynamic color functionality and think through how to best integrate it with the current window module with fresh eyes.

Loosing left Click >> Hammerspoon Error : attempt to index a nil value (field 'indicator')

I get the error below after a while. I lose the ability to left click my mouse. Right click works fine as well as everything else. Weird. Any ideas?

stack traceback: .../jesseskelton/.hammerspoon/stackline/stackline/stack.lua:73: in local 'fn' ...on.app/Contents/Resources/extensions/hs/fnutils/init.lua:130: in function 'stackline.lib.utils.filter' .../jesseskelton/.hammerspoon/stackline/stackline/stack.lua:72: in function 'stackline.stackline.stack.getWindowByPoint' ...kelton/.hammerspoon/stackline/stackline/stackmanager.lua:118: in function 'stackline.stackline.stackmanager.getClickedWindow' ...seskelton/.hammerspoon/stackline/stackline/stackline.lua:26: in function <...seskelton/.hammerspoon/stackline/stackline/stackline.lua:22> 2020-09-21 21:47:06: 21:47:06 ERROR: LuaSkin: hs.eventtap callback error: .../jesseskelton/.hammerspoon/stackline/stackline/stack.lua:73: attempt to index a nil value (field 'indicator')

Indicator not shown when stack width < minimum width of stacked window. [Original: Iterm icon is not visible]

Hi @AdamWagner

First of all thanks for writing this scripts :) nice addition to yabai πŸ’―

Grouping by stackId is buggy. Assumption to make stackId based on x+y+w+h is incorrect, as some windows can have different dimensions (for instance terminal or iterm and any other app that have weird behaviour when very narrow).

stackId = table.concat({x, y, w, h}, '|'),

Replacing

byStack = u.filter(u.groupBy(windows, 'stackId'), u.greaterThan(1)) -- stacks have >1 window, so ignore 'groups' of 1

with

byStack = u.groupBy(windows, 'stackId')

Solves it, but not sure if this is a correct fix. At least it works for me :) Could make a PR if this is the right way to fix it

Before
image

After:
image

UPD: Nah naive fix makes it more buggy :/

Indicators not visible

I've pulled the latest version (after #18) and I'm no longer seeing the indicators (with or without icons). I've tried deleting and re-cloning the repo, restarting yabai and Hammerspoon. I've also removed the yabai signals that were previously required. I'm sure I'm missing something but I can't put my finger on it. πŸ€”

❯ cat init.lua
local stackline = require "stackline.stackline.stackline"
❯ which hs
/usr/local/bin/hs

Hamerspoon console logs:

2020-08-22 22:36:44: Welcome to the Hammerspoon Console!
You can run any Lua code in here.

2020-08-22 22:36:44: -- Lazy extension loading enabled
2020-08-22 22:36:44: -- Loading ~/.hammerspoon/init.lua
2020-08-22 22:36:44: -- Loading extension: settings
2020-08-22 22:36:44: org.hammerspoon.Hammerspoon
2020-08-22 22:36:44: -- Loading extension: ipc
2020-08-22 22:36:44: -- Loading extension: fnutils
2020-08-22 22:36:44: -- Loading extension: window
2020-08-22 22:36:44: -- Loading extension: uielement
2020-08-22 22:36:44: -- Loading extensions: window.filter
2020-08-22 22:36:45: -- Loading extension: timer
2020-08-22 22:36:45: -- Loading extension: spaces
2020-08-22 22:36:45: -- Loading extension: task
2020-08-22 22:36:45: -- Done.
2020-08-22 22:36:45: -- Loading extension: json
2020-08-22 22:36:49: 22:36:49 ** Warning:   wfilter: No accessibility access to app zoom.us (no watcher pid)
2020-08-22 22:36:50: 22:36:50 ** Warning:   wfilter: No accessibility access to app Ferdi Helper (Renderer) (no watcher pid)
2020-08-22 22:36:50: 22:36:50 ** Warning:   wfilter: No accessibility access to app Messages Networking (no watcher pid)
2020-08-22 22:36:50: 22:36:50 ** Warning:   wfilter: No accessibility access to app FirefoxCP WebExtensions (no watcher pid)
2020-08-22 22:36:50: 22:36:50 ** Warning:   wfilter: No accessibility access to app FirefoxCP Web Content (no watcher pid)
2020-08-22 22:36:50: 22:36:50 ** Warning:   wfilter: No accessibility access to app FirefoxCP RDD Process (no watcher pid)
2020-08-22 22:36:50: 22:36:50 ** Warning:   wfilter: No accessibility access to app FirefoxCP Privileged Content (no watcher pid)

stackline.stackline.configManager not found

Hello, that's my first attempt at yabai + stackline.

  • My folder structure looks exactly like the one in starters guide.
  • Problem: Stackline seems to not start, no indicators and causes Hammerspoon to stop
  • OS: MacOS High sierra
    image

i'm getting this output from Hammerspoon Console
2020-11-28 19:29:55: -- Lazy extension loading enabled 2020-11-28 19:29:55: -- Loading ~/.hammerspoon/init.lua 2020-11-28 19:29:55: -- Loading extension: logger 2020-11-28 19:29:55: 19:29:55 utils: Loading module 2020-11-28 19:29:55: -- Loading extension: fnutils 2020-11-28 19:29:55: -- Loading extension: window 2020-11-28 19:29:55: -- Loading extensions: window.filter 2020-11-28 19:29:55: -- Loading extension: timer 2020-11-28 19:29:55: -- Loading extension: eventtap 2020-11-28 19:29:55: stackline: Loading module 2020-11-28 19:29:55: *** ERROR: ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: module 'stackline.stackline.configManager' not found: no field package.preload['stackline.stackline.configManager'] no file '/Users/nodge/.hammerspoon/stackline/stackline/configManager.lua' no file '/Users/nodge/.hammerspoon/stackline/stackline/configManager/init.lua' no file '/Users/nodge/.hammerspoon/Spoons/stackline/stackline/configManager.spoon/init.lua' no file '/usr/local/share/lua/5.4/stackline/stackline/configManager.lua' no file '/usr/local/share/lua/5.4/stackline/stackline/configManager/init.lua' no file '/usr/local/lib/lua/5.4/stackline/stackline/configManager.lua' no file '/usr/local/lib/lua/5.4/stackline/stackline/configManager/init.lua' no file './stackline/stackline/configManager.lua' no file './stackline/stackline/configManager/init.lua' no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline/stackline/configManager.lua' no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline/stackline/configManager/init.lua' no file '/Users/nodge/.hammerspoon/stackline/stackline/configManager.so' no file '/usr/local/lib/lua/5.4/stackline/stackline/configManager.so' no file '/usr/local/lib/lua/5.4/loadall.so' no file './stackline/stackline/configManager.so' no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline/stackline/configManager.so' no file '/Users/nodge/.hammerspoon/stackline.so' no file '/usr/local/lib/lua/5.4/stackline.so' no file '/usr/local/lib/lua/5.4/loadall.so' no file './stackline.so' no file '/Applications/Hammerspoon.app/Contents/Resources/extensions/stackline.so' stack traceback: [C]: in function 'rawrequire' ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: in function 'require' /Users/nodge/.hammerspoon/stackline/stackline/stackline.lua:13: in main chunk [C]: in function 'rawrequire' ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: in function 'require' /Users/nodge/.hammerspoon/init.lua:1: in main chunk [C]: in function 'xpcall' ...app/Contents/Resources/extensions/hs/_coresetup/init.lua:702: in function 'hs._coresetup.setup' (...tail calls...)

Stackline crash

Hi, and thank you for your work on this project.

Stackline crashes repeatedly on my Yabai setup when working with stacks, giving me this error log:

2020-10-23 21:42:28: 21:42:28 ERROR:   LuaSkin: hs.timer callback error: ...rs/RNO/.hammerspoon/stackline/stackline/stackmanager.lua:66: attempt to index a nil value (field 'integer index')
stack traceback:
  ...rs/RNO/.hammerspoon/stackline/stackline/stackmanager.lua:66: in local 'fn'
  ...on.app/Contents/Resources/extensions/hs/fnutils/init.lua:57: in function 'hs.fnutils.map'
  ...rs/RNO/.hammerspoon/stackline/stackline/stackmanager.lua:64: in function 'stackline.stackline.stackmanager.getSummary'
  /Users/RNO/.hammerspoon/stackline/stackline/query.lua:129: in function 'stackline.stackline.query.windowsCurrentSpace'
  ...rs/RNO/.hammerspoon/stackline/stackline/stackmanager.lua:14: in function 'stackline.stackline.stackmanager.update'
  /Users/RNO/.hammerspoon/stackline/stackline/stackline.lua:42: in function </Users/RNO/.hammerspoon/stackline/stackline/stackline.lua:41>

I am running on Stackline on macOS 10.14.6 (18G6032).
Latest commit on my local repo is c93a0bd so I am currently up-to-date.

Sorry for not being more precise on the title of this issue, I'm quite new to Yabai, Hammerspoon and Stackline (in fact it is thanks to your project that I'm trying Yabai).

Hammerspoon does not work with latest stackline

After taking latest pull today, hammerspoon does not start.

My init.lua looks like below:

stackline = require "stackline"
stackline:init()

Note that I have jq installed at this location /Users/pritamkadam/.nix-profile/bin/jq. But recent changelog mentions that stackline does not depend on jq hence I removed that from init.lua

When I start hammerspoon, I am getting this error:

2021-06-07 11:08:44: -- Lazy extension loading enabled
2021-06-07 11:08:45: -- Loading ~/.hammerspoon/init.lua
2021-06-07 11:08:45: -- Loading extension: window
2021-06-07 11:08:45: -- Loading extensions: window.filter
2021-06-07 11:08:45: -- Loading extension: timer
2021-06-07 11:08:45: -- Loading extension: logger
2021-06-07 11:08:45: -- Loading extension: eventtap
2021-06-07 11:08:45: 11:08:45  stackline: Loading module: stackline
2021-06-07 11:08:45:           configmgr: Loading module: stackline.configmanager
2021-06-07 11:08:45: *** ERROR: ...kadam/.hammerspoon/stackline/stackline/configmanager.lua:36: attempt to index a nil value (global 'u')
stack traceback:
	...kadam/.hammerspoon/stackline/stackline/configmanager.lua:36: in main chunk
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:657: in function 'require'
	...itamkadam/.hammerspoon/stackline/stackline/stackline.lua:11: in main chunk
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:657: in function 'require'
	(...tail calls...)
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:657: in function 'require'
	/Users/pritamkadam/.hammerspoon/init.lua:1: in main chunk
	[C]: in function 'xpcall'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:718: in function 'hs._coresetup.setup'
	(...tail calls...)


Stackline issue with Hammerspoon update 0.9.79

I got prompted to update Hammerspoon and now get this error on startup:

2020-09-20 13:04:02: stackline loading
2020-09-20 13:04:02: -- Loading extension: settings
2020-09-20 13:04:02: org.hammerspoon.Hammerspoon
2020-09-20 13:04:02: -- Loading extension: fnutils
2020-09-20 13:04:02: -- Loading extension: ipc
2020-09-20 13:04:02: -- Loading extension: window
2020-09-20 13:04:02: -- Loading extensions: window.filter
2020-09-20 13:04:02: *** ERROR: ...n.app/Contents/Resources/extensions/hs/window/filter.lua:1431: attempt to index a nil value (field '_element')
stack traceback:
	...n.app/Contents/Resources/extensions/hs/window/filter.lua:1431: in upvalue 'startAppWatcher'
	...n.app/Contents/Resources/extensions/hs/window/filter.lua:1559: in upvalue 'startGlobalWatcher'
	...n.app/Contents/Resources/extensions/hs/window/filter.lua:1649: in upvalue 'checkTrackSpacesFilters'
	...n.app/Contents/Resources/extensions/hs/window/filter.lua:592: in function <...n.app/Contents/Resources/extensions/hs/window/filter.lua:518>
	(...tail calls...)
	...e/dotfiles/hammerspoon/stackline/stackline/stackline.lua:12: in main chunk
	[C]: in function 'rawrequire'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:651: in function 'require'
	/Users/liquid/git-home/dotfiles/hammerspoon/init.lua:5: in main chunk
	[C]: in function 'xpcall'
	...app/Contents/Resources/extensions/hs/_coresetup/init.lua:702: in function 'hs._coresetup.setup'
	(...tail calls...)

Stackline icon not clickable with my multi-monitor layout

Red arrow is the click point.
Purple border is the icon area.
Blue Border shows that actually I put my MacBook in front of my monitor and MacBook own the system topbar so I found the coordinate of the click is kind of negative value. So the hittest might fail because of this.
image

If I move the system top bar to the external monitor, then the icon could be clicked but still offset (less accuracy of icon frame and click point)

macOS: bigSur 11.0.1 (20B29)
version:

commit 8c1533e (HEAD -> master, origin/master, origin/HEAD)
Author: Jerred Shepherd [email protected]
Date: Sat Dec 12 13:25:06 2020 -0800

Fix link (#54)

Adjust space padding when no stacked windows present?

I'm wondering if there is any advice on how to configure .yabairc or .skhdrc i.e. with signals or keybindings to detect when a space has a window stack and open up the padding to accommodate stack icons and then go back to tighter padding when there are no stacks?

Not really reactive using yabai -m window --insert stack

I just installed stackline, I'm not sure if this is really an issue or I am doing something wrong.

In my skhdrc I have

ctrl + alt - i : yabai -m window --insert stack

, this is the main way I create stacks.

However, looks like hammerspoon does not update the stackline icons until I reload the config.

in

πŸ€”

Eliminate the 0.3s sleep intentionally slowing down state query via yabai

The unfortunate sleep command
Sadly, on a 16" "macbook pro, at least 0.03 delay is required to ensure yabai -m query … returns the focused window and not the previously focused window. See bin/yabai-get-stacks.

Without the sleep, the active stacked-window indicator remains on the previously active stacked-window once every ~1 in 5 focus events β€” particularly when changing focus rapidly.

Why does yabai query occasionally not return new state when called by Hammerspoon's hs.window.filter.windowFocused event?

Hypothesis: if a yabai query blocks a subsequent query, sequential calls may accumulate and eventually fall behind the current state? Actually, this doesn't really make sense, wouldn't this mean the last call would be late, and therefore be slow, but reflect the latest state?

ALTERNATIVE no. 1
For events that will certainly result in a stack indicator update (e.g., windowFocused), we could call this continuously w/ exponential backoff until the response is different.

This seems like it would provide the best of both worlds: responsive updates when the yabai query reflects the change, and eventual consistency when it doesn't.

The cost is additional calls to yabai -m query …, which may be significant. There may be other costs I'm not considering, e.g., what happens when there are 5 focus events in 5 seconds?

ALTERNATIVE no. 2
Avoid shelling out to yabai at all and instead synthesize stacks entirely in hammerspoon. This is the approach recommended in #8.

sleep 0.03

yabai -m query --windows --space \
  | jq --raw-output --compact-output --monochrome-output '
      map(del(.title))                             # titles may break lua json parsing
    | map(select(
      .subrole == "AXStandardWindow" and  
      .visible == 1))                              # minimized == 0 may be preferrable?
    | map(.frameFlat = "\(.frame.x)|\(.frame.y)")  # frame x,y to string to group wins β†’ stacks
    | sort_by(.["stack-index"])
    | group_by(.frameFlat)                         # … the aforementioned grouping
    | map(select(length > 1))                      # we only care about *stacks*, which contain > 1 window
    '

Show window title next to the indicator

Hey, thanks a lot for the stackline, it's really useful.

In my setup I'm working with multiple windows of the same app (IntelliJ in my case) and navigating to the given one requires remembering the order of them (or browsing until you find what you look for).

It could be useful to show the titles next to the indicators. This would be quite intrusive so I was thinking of showing them only for a limited period of time since the last focus change.

I tried looking at the code myself but my lack of knowledge of both Lua and hammerspoon API made implementing it a real challenge.

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.