Code Monkey home page Code Monkey logo

rwind's Introduction

RWind - The Racket Window Manager

An extensible window manager written in the Racket programming language, meant to be highly customizable.

There is an RWind mailing list.

First some warnings:

  • Backward compatibility will not be ensured in the 0.x branch.
  • Due to a security issue in the server, the current version should not be used on multiple user computers, unless the server is disabled. Use at your own risk.

Current features

  • Stacking and tiling support
  • Client command line (repl)
  • Customization of key bindings and mouse bindings
  • Workspaces with two modes:
    • single mode: one workspace over all monitors
    • multi mode: one workspace per monitor
  • Xinerama and RandR support
  • Fullscreen
  • Currently little ICCCM/EWMH compliance

All these features are in development stage.

Installation & quick start

1) Install Racket

Download and install Racket at https://download.racket-lang.org

Note: Racket BC is currently recommended, as some FFI segfaults may occur with Racket CS.

You may need to set your PATH environment variable.

2) Install RWind

Type:

raco pkg install --auto --update-deps rwind

(raco is provided with Racket, so it should be in your path)

This will also install missing Racket dependencies such as the x11 Racket package.

You may also need to install libedit (installed by default on Ubuntu at least, but not on Gentoo). See here if installation fails due to this missing dependency.

3) Configure RWind

As a normal user (not a super-user), type:

racket -l rwind/configure

And follow the instructions. This creates a default RWind configuration file, then it asks you to choose between a session manager or a xinit/startx configuration. If you choose a session manager configuration, it will abort and you will need to re-type the above command preceded by sudo. These two steps are required because the first configuration files must be owned by the user.

You can reconfigure RWind at any time.

4) Start RWind

a) If you chose a session configuration, go back to the login screen. You should now see RWind in the login options.

b) If you chose a xinit/startx configuration, in a virtual terminal (Ctrl-Alt-F1 or Ctrl-Alt-F2, etc.), type the following:

xinit .xinitrc-rwind -- :1 &

You may need to modify the display :1 to :2 for example if :1 is not available. The default .xinitrc-rwind is a simple example file that you may want to edit to fit your needs. By default, you need to close the xterms to exit the session.

Default configuration and customization

Upon configuration, the file config.rkt was created. This is where all the RWind customization is done. By default, you can open this file within RWind by pressing Alt-F11 (this can also be changed in the configuration file). Take a look at this file to know what keybindings are defined. You can also of course add your own keybindings.

The default window policy is stacking (as for most traditional window managers), but you can easily change it to tiling in the configuration file. With the tiling policy, several layouts are possible (mainly uniform and dwindle). To choose a layout, specify so in the file:

(current-policy (new policy-tiling% [layout 'dwindle]))

If you edit the configuration file, you will need to restart RWind to take the changes into account, probably by pressing the keybinding as defined in this very file. You don't need to recompile RWind, just restart it.

The client

The client is a console where you can evaluate Racket expressions and communicate with the window manager. It can be opened in a terminal with:

racket -l rwind/client

For example, place the mouse pointer on a window and type in the console:

> (window-name (pointer-window))

Or:

> (move-window (pointer-window) 10 40)

The list of available symbols provided by RWind is given by:

> (known-identifiers)

All bindings of #lang racket are available too.

You can get help on a known identifier with:

> (describe 'focus-window)

You can search among the list of identifiers with:

> (search-identifiers "window")

You can get the list of existing layouts for the tiling policy:

> (policy. get-layouts)

The layout can be changed immediately:

> (policy. set-layout 'dwindle)

Each workspace can have its own layout:

> (policy. set-workspace-layout 'uniform)

To reset the layout of a workspace to the default one:

> (policy. reset-workspace-layout)

Updating RWind

RWind has some dependencies, in particular the X11 FFI bindings, that will probably need to be updated with RWind. To do this automatically, specify the --auto option to raco update:

raco update --auto rwind

Your RWind configurations file will not be modified by the update. This also means that any new feature that may appear in the new versions of these files will not be added to your files. You can reconfigure RWind, and you will be asked if you want to replace the existing config.rkt file.

Debugging

Because RWind heavily relies on the X11 collection, a large part of the debugging happens an the interface between the two.

Create symbolic links to the scripts user-files/.xinitrc-rwind-debug and user-files/rwind-debug in your home directory, or copy these files.

Compile rwind and x11 in debug mode with $ user-files/compile-rwind debug. Basically, it removes all previous compilations of the two collections and compiles it with some flags.

Finally, start RWind from a non-X terminal (say, Ctrl-Alt-F2):

xinit .xinitrc-rwind-debug -- :2 &

Then all error messages are redirected to ~/rwind.log. You should see lines starting with "RW:", and lines starting with " X:" (for the X11 lib). You can also track the error messages from within RWind with tail -f ~/rwind.log.

rwind's People

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

Watchers

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

rwind's Issues

Dual monitors of unequal resolution not being handled properly

I have two monitors of unequal resolution. One is 1920x1080, and the other is 1366x768.

When rwind starts in tiled mode, two xterms are started, one per monitor, and the xterm on the smaller monitor extends in to the window of the larger monitor. Also, neither xterm is sized appropriately for the monitor it is on (they're both bigger).

Sometimes loses focus

After a number of clicks in and out of windows, RWind sometimes loses track of the mouse focus. Changing desktop restores it.

Why racket? Racket memory usage is very big!

I know that incorrect place to ask this... But why racket? I try to run example which exists in the racket and it's memory usage is biggest. Webserver - 100Mb... Sorry but this very stange. Clean rocket interpretator use 38Mb!!!

SawFish in this case leader. Since SF use 5Mb and rep which is loaded with it 7Mb.

Sorry but it's very strange for window manager, eat such memory size.

Add Taskbar

I have been thinking for a while on what RWind would really need next and the first thing that came to mind is a taskbar. I'm not sure how this would be implemented, as I haven't taken a single look at the x11 library, but here are some of my thoughts on what properties it should have:

  • The taskbar will appear on each workstation and on any of the four sides of the screen
  • It will have its own list of open windows for that workstation, of course independent of the other workstations
  • System tray
  • A clock!

I suspect this might end up as more of a long-term goal, but as I said earlier, I have no idea what what needs to happen before this can be implemented.

Undocumented rwind/client dependency on libedit.so.3

When I tried racket -l rwind/client I got an error:

ffi-lib: couldn't open "libedit.so.3" (libedit.so.3: cannot open shared object file: No such file or directory)
  context...:
   /usr/share/racket/collects/ffi/unsafe.rkt:117:0: get-ffi-lib10

It seems this is because I didn't have libedit installed on my machine, as the rwind README did not mention it as a requirement.

Furthermore, once I did have it installed, I continued to get the same error because on Gentoo Linux (which is what I'm using) that library is installed as libedit.so.0.0.47, not libedit.so.3. Also, confusingly, the Gentoo package version for libedit is 20130712.3.1, not 0.0.47 or 3 or 3.1. Anyway, once I created this symlink, it worked: ln -s /lib64/libedit.so.0.0.47 /lib64/libedit.so.3

Crashes on mouse drag with default config

Here is the rwind log. Looks like the call to keymap-event-window for mouse movement is returning #f for some reason. Is there anything I can do to help debug this?

RW: 
 *** New session on Sunday, November 18th, 2012 6:11:54pm on display :0 ***
RW: (() (Mod2Mask) (LockMask) (LockMask Mod2Mask))
RW: global keymap:
'#hash(((28 KeyPress ControlMask Mod1Mask)
        .
        #<procedure:...fig/rwind/config.rkt:18:10>)
       ((1 ButtonPress ControlMask) . #<procedure:...RWind/keymap.rkt:330:15>)
       ((3 ButtonRelease ControlMask)
        .
        #<procedure:...RWind/keymap.rkt:339:15>)
       ((67 KeyPress Mod4Mask) . #<procedure:...fig/rwind/config.rkt:29:10>)
       ((68 KeyPress Mod4Mask) . #<procedure:...fig/rwind/config.rkt:31:10>)
       ((76 KeyPress Mod1Mask) . #<procedure:...fig/rwind/config.rkt:26:10>)
       ((3 ButtonMove ControlMask) . #<procedure:...RWind/keymap.rkt:368:4>)
       ((68 KeyPress Mod1Mask) . #<procedure:...fig/rwind/config.rkt:22:10>)
       ((3 ButtonPress ControlMask) . #<procedure:...RWind/keymap.rkt:330:15>)
       ((96 KeyPress Mod1Mask) . #<procedure:...fig/rwind/config.rkt:24:10>)
       ((1 ButtonMove ControlMask) . #<procedure:...RWind/keymap.rkt:349:4>)
       ((1 ButtonRelease ControlMask)
        .
        #<procedure:...RWind/keymap.rkt:339:15>)
       ((1 ButtonPress) . #<procedure:...rwind/config.rkt:36:13>)
       ((9 KeyPress Mod1Mask) . #<procedure:...are/RWind/keymap.rkt:384:12>)
       ((54 KeyPress ControlMask Mod1Mask)
        .
        #<procedure:...fig/rwind/config.rkt:20:10>))
RW: window keymap:
'#hash()
window-apply-keymap 175
window-apply-keymap 16777217
window-apply-keymap 16777217
window-apply-keymap 16777218
window-apply-keymap 16777218
window-apply-keymap 16777219
window-apply-keymap 16777219
RW: Activating workspace 0
RW: Adding window 4194305 to workspace #(struct:workspace First 16777217)
RW: Adding window 12582913 to workspace #(struct:workspace First 16777217)
RW: Adding window 14680065 to workspace #(struct:workspace First 16777217)
RW: Adding window 14680067 to workspace #(struct:workspace First 16777217)
RW: Adding window 12582921 to workspace #(struct:workspace First 16777217)
RW: Adding window 12582925 to workspace #(struct:workspace First 16777217)
RW: Adding window 12582929 to workspace #(struct:workspace First 16777217)
Srv: Opening listener... Srv: Ok.
Srv: Waiting for client... RW: Event type: ConfigureRequest
RW: Event type: KeyPress
RW: KeyPress: key-code: 28 (t) modifiers: (ControlMask Mod1Mask)
Binding (28 KeyPress ControlMask Mod1Mask) not found
Binding 28 ((ControlMask Mod1Mask)) found, calling thunk
RW: Event type: KeyRelease
RW: Unhandled event (KeyRelease)
RW: Event type: ClientMessage
RW: Client message: window: 18874373 message-type: 333 format: 32
RW: Event type: ConfigureRequest
RW: Event type: MapRequest
RW: Mapping new window
RW: Adding window 18874373 to workspace #(struct:workspace First 16777217)
RW: Event type: ButtonPress
RW: ButtonPress x: 416 y: 330 x-root: 416 y-root: 330 button: 1 modifiers: (ControlMask) window: #f subwindow: #f
Binding (1 ButtonPress ControlMask) not found
Binding 1 ((ControlMask)) found, calling thunk
*** Error: BadWindow (invalid Window parameter)
XWindowAttributes-x: contract violation
  expected: XWindowAttributes?
  given: #f
  context...:
   XWindowAttributes-x
   window-position
   /home/asumu/software/RWind/keymap.rkt:349:4
   /home/asumu/software/RWind/keymap.rkt:330:15
   call-binding
   /home/asumu/software/RWind/events.rkt:158:19: loop2
   /home/asumu/software/RWind/events.rkt:154:2: loop
   /home/asumu/software/RWind/rwind.rkt:87:2: temp3
   /home/asumu/software/RWind/rwind.rkt: [running body]

(gnome-terminal:14080): Gdk-WARNING **: GdkWindow 0x120002e unexpectedly destroyed

(gnome-terminal:14080): Gdk-WARNING **: GdkWindow 0x1200005 unexpectedly destroyed

(gnome-terminal:14080): Gdk-WARNING **: The program 'gnome-terminal' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadWindow (invalid Window parameter)'.
  (Details: serial 400 error_code 3 request_code 141 minor_code 42)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the GDK_SYNCHRONIZE environment
   variable to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)

Float specific windows in tiling mode

Selecting a specific window to have it float above the other windows in a tiling workstation would be amazing. This is a feature in Awesome window manager and it's incredibly useful.

Let server listen on + client connect to unix domain socket

A possible solution to the "security issue" mentioned in the README:

Since unix domain sockets are protected via unix file permissions, there's no further security measures needed.

The server should create and listen on a socket file, that belongs to the user running the window manager and should be created with restrictive file permissions (i.e. set umask accordingly).

The client should connect to that socket.

To make the code portable to machines with non-local filesystems, there should be a list of paths that is tried for socket creation/connect:

  • some subdirectory of $HOME, might fail for some remote filesystems
  • /tmp/$USER/, must be created first and checked for permissions

Also socket creation might be vulnerable to a race condition, which must be prevented in the server code.

Rough draft, I might try my hand at this when/if I find the time. First step is to figure out how to use unix-domain-sockets in racket.

Drawback of this approach is of course that client connections won't work across the network any more, but a proper authentication scheme would be needed for this, which imho is overkill for a window manager client.

I dimly remember sawfish uses unix-domain sockets, too, but it's been a long time since I used it.

Feature request: tabbed mode

The i3 window manager has a "tabbed" mode, which works like this:

  • Only a single window is ever displayed on any monitor
  • All other windows on the same monitor are hidden behind the front window
  • The title bars of every window appear next to one another, with the front window's title bar (and other window decorations) being of a different color from the rest so the user can easily tell them apart.
  • There are keyboard shortcuts to allow bringing the next/previous window to front.

I'd like to request that something like this mode be made for rwind.

Bug: reset-workspace-layout arity mismatch

rwind-client> 
(policy. reset-workspace-layout)
-> [dict-remove!: arity mismatch;
 the expected number of arguments does not match the given number
  expected: 2
  given: 1
  arguments...:
   (workspace 1 "1" 16777218 '(25165827 25165825) 25165827)]

Use racket-reloadable

The racket-reloadable library is designed for programs that stay on for long amounts of time like servers or, say, a window manager. It splits up code between permanent and reloadable parts, which got me thinking about this project, which I think could benefit from using such a library, what with modifying configuration files or even sections of the window manager itself.

Application-Specific Float

Is there a way to get a specific application to "float" (i.e. ignore tiling rules currently set)? Using RWind in tiling mode is great, but when I want to watch a video, I have to switch to another workstation before mplayer can spawn. If I don't do this, it'll be tiled like the others and making it go fullscreen does nothing.

RWind crashes on window close

I open a terminal, things work okay. I open Firefox, things work okay. I close any window, RWind goes down. Inside .xsession-errors is the following:

The program 'racket' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadWindow (invalid Window parameter)'.
  (Details: serial 896 error_code 3 request_code 20 minor_code 0)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)

I tried running RWind with exec racket --sync -l rwind &, but it seems --sync isn't a valid Racket switch!

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.