prabirshrestha / dwm-win32

dwm port of tiling manager to Window
MIT License
480 stars 38 forks source link

Multi Monitor Support #8

Open PascalSenn opened 4 years ago

PascalSenn commented 4 years ago

I am currently using bug.n but kind of want to break free of a autohtokey dependency. What bug.n solved really nicely is mutlimonitor. having the ability to change displayed tags (like left on 1 right on 3) is super helpful.

yamhackasi commented 3 years ago

Hello, some news about multi monitor?

prabirshrestha commented 3 years ago

No plans to support multimonitor in C, but I have been working on and off on lua bindings which will support multi monitor apis.

https://github.com/prabirshrestha/dwm-win32/blob/master/docs/api.md#display-mod

local dwmdisplay = require 'dwm.display'
for _, displayid = ipairs(dwmdisplay.displays()) do
   print(displayid)
end
local display = dwmdisplay.display(displayid)
print(display.id)
print(display.x)
print(display.y)
print(display.width)
print(display.height)
gluonman commented 3 years ago

I'm testing this out and I have a dual-monitor setup, and so far I'm finding that dwm-win32 is forcing me to do everything on only my primary display, and so I have to manually drag windows over to my secondary display that I wish to place there and then manually size and position them (defeating the purpose of a dynamic window manager). Of course, then the moment I open another window, close a window, or make some change, everything gets redrawn back to the primary display, ruining my setup and typically trying to stuff way too many windows onto only one display making my apps unusable. It makes it entirely counter-productive to use dwm-win32 on anything but a single-monitor setup. Granted, for single-monitor, dwm-win32 is truly awesome and just the bug.n alternative I've been looking for. But for dual-monitor, it's a non-solution.

However, you link to the lua binding that can be used with multi-monitor apis. Can you expand on that? Because I'm not ready to give up on dwm-win32 just yet. Is there a way to use your binding to extend the functionality of dwm-win32 to support a second monitor? If I can get dwm-win32 working with my dual displays more or less the same way dwm handles dual displays in Linux, then I'm sticking with it. I specifically set out to find something better than bug.n, something that feels like a more true port of dwm and a more complete solution. And dwm-win32 comes so close to being just that perfect alternative to bug.n that I was looking for, except for this one limitation. Can you help me make it work?

nir9 commented 3 years ago

I see that this is highly requested, looking into how this can be added natively in C. Also looking into the lua bindings, though in my opinion they do not provide the complete solution due to the fact that they only let you select a display to use and are not actually true-multi-monitor support like what you would expect from i3 for example.

Will update here on any progress.

gluonman commented 3 years ago

Thanks, I appreciate you working on this multi-display feature. I look forward to updates on this.

prabirshrestha commented 3 years ago

I personally use only single monitor but multi monitor is something I have wanted to add. Lua bindings is working in progress and not ready for consumption. @nir9 if you are looking to add support please work on the lua bindings instead. You can see some of the apis documented here.

This is really where the lua code starts. https://github.com/prabirshrestha/dwm-win32/blob/fef9b20b3504d4761c7dba6277159a85227cbce4/src/dwm-win32.c#L1191-L1195 It starts by initializing lua and dwm mods (modules) and then finally loading the %USERPROFILE%\.config\dwm\init.lua if it exists. Feel free to create that file add the following line. You will see 'Hello world being shown in message box.

local dwm = require 'dwm'
dwm.log('Hello World!')

If you want to get list of all displays you can do the following.

local dwmdisplay = require 'dwm.display'
for _, displayid = ipairs(dwmdisplay.displays()) do
   print(displayid)
end

The concept of mods (modules) is to provide some sort of win32 apis in the lua world. You can find all the mods here. https://github.com/prabirshrestha/dwm-win32/tree/master/src/mods.

I don't have multi monitor but there is an api that can already move /resize a client (window). Need to support display (monitor) in this api.

dwmclient.position(clientid, {
    x = 10,
    y = 20,
    width = 200,
    height = 300,
})

@nir9 if you are looking into adding features I would suggest to add support for lua bindings and allow everything to be done in the user land and then we can port layouts and others to the core so it is easy for anyone to start.

I was working on hotkey apis but currently stopped since busy with other projects. Currently the only thing that is missing is hotkey api and some sort of event emitter to subscribe for client (window) open/close events. Then we can do all the layout in lua.

local clientmod  = require 'dwm.client'
local hotkeymod = require 'dwm.hotkey'
hotkeymod.bind({ key = 'c', mods="Ctrl", function(e) { clientmod.close(e.clientid)  } })

My hope is to provide some sort of built in layouts so given list of client ids one can easily layout whatever they want. If init.lua is not present then it will work as it is now but with multiple monitor support. So as user you get full control of it.

nir9 commented 3 years ago

@prabirshrestha Really cool I will look into it, and continue your work on the Lua multi-monitor support :)

How exactly will the default behavior (if the init.lua isn't present ) will work? Will it have a default lua script that it will load? will the user have the ability to take the default lua script and expand it?

How do you imagine this feature in the end working with the Lua?

prabirshrestha commented 3 years ago

We ship the default lua script so the user starting it for the first time will never have to configure anything and they get the exact experience we have now. It is really important to have this WOW effect in the first 5sec the user uses dwm-win32.

We will also provide an easysetup mod which allows anyone to easily setup the dwm and change few shortcuts.

local dwm = require('dwm.easysetup')
dwm.start({
   mod = 'alt',
   keys = {
     { "mod|ctrl", "q", dwmgr.quit }
   },
   rules = {
      { title = "Google Chrome", floating = false, ignoreborder = true }
   },
   bar = {
      position = "top",
   },
   showexploreronstart = true
})

Most will most likely stop here.

We will also ship with low level apis. easysetup will be using this low level api internally.

local tilelayout = require("dwm.layout.tile")
local gridlayout = require("dwm.layout.grid")
local moddisplay = require("dmw.display")

local displayid = 1 -- assume monitor/display id
local display = moddisplay.display(displayid)
local clientids = {1,2,3 } -- assume this as hwnd i.e. window id

tilelayout.layout({ clients = clientids, display = displayid, x = display.x, y = display.y, width = display.width, height = display.height })

I haven't fully decided on the apis but should give a high level thought. Basically C is there to provide low level win32 api and lua is there to customize it further and I'm hoping there will be more contributions in lua since C is not easy.

Possibilities it can bring is infinite.

nir9 commented 3 years ago

Got it and agree with the vision (though I don't know Lua so learning now lol). Now playing around with the hello world you did with ~.config\dwm\init.lua and it is really cool!!!

About the previous question, what do you think specifically would be the default Lua behavior with multiple monitors - would the default Lua already setup all the monitors and allow moving windows between?

prabirshrestha commented 3 years ago

The way I envision is to have an api that can get all client for a display and then client.position api can also take the displayid which can move to a different display. Then all we need is register a hot key that can move a client to another display and call layout on the displays.

goal is to get these lego blocks and rest should be lot easier.

I went with lua since all my tools are using lua such as awesomewm on Linux, wezterm, neovim. So good to have one language that can configure everything.

gluonman commented 3 years ago

Cheers to adding multi-monitor support and definine a config file. I'm used to just being able to config dwm by editing the config.h and recompiling, though. Not all of us work in lua-heavy environments. A part of what attracted me to this project was that I was imagining it to be maturing into a port of dwm for Windows in which my config.h config changes in dwm on my instances of Linux would be roughly relevant in Windows, making it easy for me to port my own modifications, added layouts, etc. and thus sync my settings across platforms. I got this impression when I noticed your inclusion of a few dwm plugins in your source (bstack, fibonacci, and gaplessgrid), and I have a fair-sized list of plugins I use in my dwm config on my Linux machines. Where the goal is to mimic as closely as possible one's favourite Linux workflow within Windows, I imagine a lot of dwm users like me might want to simply be able to port the plugins they are used to using and config.h configs into their Windows configs without having to reconstruct all those modifications in lua (i.e. keeping the configuration within C where the config work has already been done). I understand the lua direction from the perspective of someone who does mostly everything in lua everywhere, but I'm wondering if for some users it may not amount to ease of dwm configuration, but more like added work, especially if they already have a dwm config in C they want to just port over. Maybe not super hard work (I haven't learned lua yet, but I can't imagine modifying an init.lua is that different from modifying a config.h), but it would still be nice to have the option of being able to just config dwm-win32 traditionally by playing with the C source. I'm going to try to play around with your source on my own machine and test out a solution to use a config.h to config dwm-win32 and then be able to test out my own dwm configs from Linux and see how well I can get them working. If not for this project, at least for myself, if that's okay.