Git Product home page Git Product logo

hudkit's Introduction

Hudkit 

Transparent click-through web browser overlay ("HUD") over your whole desktop, using WebKit.

If you know web development, you can use Hudkit to make the coolest statusbar in existence, or SVG desktop fireworks, or whatever else you can think of using a fullscreen transparent web view for.

Features

  • Works with multiple monitors, and connecting/disconnecting them.
  • Has a JavaScript API, so scripts on the page can query monitor layout and change which areas of the overlay are clickable, for example.
  • Small executable. Uses native GTK and WebKit libraries.
  • Supports modern web APIs like WebSockets, WebAudio, WebGL, etc.

Platforms:   ✔️ Linux (X11) 🚫 Linux (Wayland)  🚫 Windows  🚫 OS X

Quick start

cd /tmp
git clone https://github.com/anko/hudkit.git
cd hudkit
make
./example/run.sh

If make complains, check dependencies.

You should see something like this, if you have 2 monitors:

hudkit example running on 2 monitors

The code for what you see there is in the example/ directory. It contains some explanatory comments, so it might make a good starting point for your experiments. If you come up with a (fairly compact) example of your own, please PR.

To open Web Inspector targeting the example page, ./example/run.sh --inspect.

Usage

USAGE: ./hudkit <URL> [--help] [--webkit-settings option1=value1,...]

    <URL>
        Universal Resource Locator to be loaded on the overlay web view.
        For example, to load a local file, you'd pass something like:

            file:///home/mary/test.html

        or to load from a local web server at port 4000:

            http://localhost:4000

    --inspect
        Open the Web Inspector (dev tools) on start.

    --webkit-settings <settings>
        The <settings> should be a comma-separated list of settings.

        Boolean settings can look like
            option-name
            option-name=TRUE
            option-name=FALSE

        String, integer, and enum options look like
            option-name=foo
            option-name=42

        To see settings available on your system's WebKit version, their
        valid values, and default values, pass '--webkit-settings help'.

        To see explanations of the settings, see
        https://webkitgtk.org/reference/webkit2gtk/stable/WebKitSettings.html

    --help
        Print this help text, then exit.

    All of the standard GTK debug options and env variables are also
    supported.  You probably won't need them, but you can find a list here:
    https://developer.gnome.org/gtk3/stable/gtk-running.html

JavaScript API

JavaScript on the web page context has a Hudkit object, with these properties:

async Hudkit.getMonitorLayout()

Return: an Array of {name, x, y, width, height} objects, representing your monitors' device names and dimensions.

Example:

const monitors = await Hudkit.getMonitorLayout()

monitors.forEach((m) => {
  console.log(`${m.name} pos:${m.x},${m.y} size:${m.width},${m.height}`)
})

Hudkit.on(eventName, listener)

Registers the given listener function to be called on events by the string name eventName.

Currently listenable events:

  • monitors-changed: fired when a monitor is logically connected or disconnected, such as through xrandr.

    No arguments are passed to the listener. Call Hudkit.getMonitorLayout to get the updated layout.

  • composited-changed: fired when the ability of your desktop environment to render transparency changes; typically when your compositor is killed or restarted.

    The main reason this exists is so if you accidentally kill your compositor, you won't be stuck with the now fully opaque overlay window blocking your whole desktop, as long as your page listens for this event and calls window.close() in response.

    Arguments passed to listener:

    • haveTransparency (Boolean). True if compositing is now supported, false otherwise.

Hudkit.off(eventName, listener)

De-registers the given listener from the given eventName, so it will no longer be called.

async Hudkit.setClickableAreas(rectangles)

Sets which areas of the overlay window are clickable. By default, it is not clickable. The given area replaces the previous.

Parameters:

  • rectangles: Array of objects with properties x, y, width, and height. Other properties are ignored, and missing properties are treated as 0. Can be an empty Array, to make everything non-clickable.

    The area of the desktop represented by the union of the given rectangles become input-opaque (able to receive mouse events). All other areas become input-transparent.

Return: undefined

Example:

// Make a tall narrow strip of the overlay window clickable, in the top left
// corner of the screen. The dimensions are in pixels.
Hudkit.setClickableAreas([
  { x: 0, y: 0, width: 200, height: 1000 }
], err => console.error(err))

Notes:

  • If the Web Inspector is attached to the overlay window, the area it occupies is automatically kept clickable, independently of calls to this function.

  • When monitors are connected or disconnected, your clickable areas are reset to nothing being clickable, because their positioning would be unpredictable. Subscribe to the 'monitors-changed' event (Hudkit.on('monitors-changed', () => { ... })) and update your clickable areas accordingly!

async Hudkit.showInspector([attached])

Opens the Web Inspector (also known as Developer Tools), for debugging the page loaded in the web view.

Parameters:

  • attached: Boolean. If true, starts the inspector attached to the overlay window. If false, start the inspector in its own window. (Optional. Default: false.)

Return: undefined

ℹ️ You can also start the inspector with the --inspect flag. That's usually better, because it works even if your JS crashes before calling this function.

Other Web APIs that work specially

Install

In the root directory of this project,

make

If you're missing any dependencies, the error should tell you which.

Dependencies

You'll need—

  • Standard C compilation tools: make, pkg-config, and any C compiler of your choice (gcc or clang, probably).

    Any Linux distro has these; many have them installed by default. If not, consult your distro's documentation on how to install them. (Many distros have a single package containing all the C tools, for convenience, like Arch's base-devel package.)

  • GTK 3, and a corresponding webkit2gtk.

    On Arch, the packages are called gtk3 and webkit2gtk.

    On Void, they are gtk+3-devel and webkit2gtk-devel.

    On Ubuntu, they are libgtk-3-dev and libwebkit2gtk-4.0-devel.

    On Mint, they are libgtk-3-dev and libwebkit2gtk-4.0.

    If you build on another distro, I'm interested in how it went.

Bugs

Probably. Report them.

FAQ

Is it safe to direct Hudkit at some random untrusted web page on the internet?

No. Hudkit is built on a web browser engine, but is not intended for use as a general-purpose web browser. The window.Hudkit object and other background stuff are exposed to every page Hudkit loads. Although I've tried my best to mitigate possible attacks, the API simply is not designed to be exposed to the full badness of the wider internet.

Please point Hudkit only at a locally hosted web pages, unless you really know what you're doing.

How can I ensure my HUD doesn't accidentally load remote resources?

Define a Content-Security-Policy (CSP), like you'd do when developing any other web page. Hudkit supports those through WebKit.

I recommend the following: Add this meta tag inside your document's <head>:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'">

This makes that page only able to load resources from the same host it was loaded from (your local computer). All requests to anywhere else are blocked. The 'unsafe-inline' part allows inline <script> and <style> tags, which are innocuous if you're never loading remote resources anyway.

You can test this by e.g. adding a <img src="http://example.com/"> tag to your page. You'll see a log entry like this when it gets blocked:

CONSOLE SECURITY ERROR Refused to load http://example.com/ because it appears
in neither the img-src directive nor the default-src directive of the Content
Security Policy.

For further documentation on CSP, consult MDN Web Docs or content-security-policy.com.

Hudkit says my screen doesn't support transparency. What does this mean?

You're probably running a plain window manager (like i3, XMonad, or awesomewm), which doesn't have a built-in compositor. So you'll need to install and run a standalone compositor. I recommend compton, or picom.

I can't type anything into the Web Inspector while it's attached to the overlay window!

Yep, it's a known problem. You can work around it by detaching the web inspector into its own window, with one of the buttons in the top-left corner. It works normally when detached.

This bug is hard to fix for complex technical reasons: In short, we have to set X11's override-redirect flag on the overlay window, to guarantee that window managers cannot reposition it, reparent it, or otherwise mess with it. A side-effect of doing this is that the window does cannot receive input focus, which is fine for mouse events (since they aren't dependent on input focus), but it means no keyboard events. Unless you grab the keyboard device, which has its own problems.

My currently running Hudkit instance's page is in a weird state that I want to debug, but I forgot to pass the --inspect flag, and restarting it would lose its current state. What do?

You can send the Hudkit process a SIGUSR1 signal to open the Web Inspector. For example, killall hudkit --signal SIGUSR1.

Why am I getting a SyntaxError when I try to await a Hudkit function?

Probably because you're trying to use await at the top-level of your JavaScript file. This wart in the JavaScript standard is unfortunate, and the wording of WebKit's error message for it even more so.

The fix is to create an async function at the top-level, and immediately call it, doing all of your async stuff inside it:

(async function () {
  // You can use `await` here
})()

This will improve in the near future: There is a TC39 proposal for top-level await, which is backed by WebKit developers, and implementation is in progress.

Why is Xvfb complaining about extension "GLX" missing on display ":99" if I run the automated test?

Probably because you're running an Nvidia proprietary driver which are kind of garbage. The test starts a background instance of X11 so your desktop's settings don't interfere with it, but inside that context OpenGL is randomly bricked on some versions of the proprietary NV driver, and on some versions it works. The actual program should work just fine either way though. Try the example/.

Related programs

  • Electron. I've heard it's possible to make Electron click-through and fullscreen. I have not gotten it to work, but maybe you can? Let me know if you do.

    Possible starting point: Start electron with --enable-transparent-visuals --disable-gpu. Call win.setIgnoreMouseEvents, set all the possible "please dear WM, do not touch this window"-flags, call the screen API for monitor arrangements and position your window accordingly. Sacrifice 55 paperclips to Eris of Discordia, kneel and pray.

JS libraries that I think work well with Hudkit

  • dnode makes it possible to make remote procedure calls from JS in the web page to JS on a web server.
  • SockJS lets is a simple abstraction over WebSockets, for transferring data otherwise.
  • D3 is a great data visualisation library.

Programs that I think work well with Hudkit

  • xkbcat can capture keystrokes everywhere in X11, for making a keyboard visualiser for livestreaming, or for triggering eye candy.
  • sxhkd is a fairly minimal X11 keyboard shortcut daemon. Can use it to run arbitrary commands in response to key combinations, such as throwing data into a named pipe read by a locally running web server that's in contact with hudkit by WebSocket.
  • mpv with the --input-ipc-server flag can be queried for the currently playing music track. Various other music players can do this too if you google around.
  • sensors can show hardware temperatures and fan data.

License

ISC.

hudkit's People

Contributors

anko avatar waldyrious 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hudkit's Issues

Hudkit going behind windows?

The title explains the issue pretty clearly.

When opening hudkit with hudkit https://localhost:5173 with a test red side bar, it displays above all windows.

When opening a new window, it goes behind the windows, like the following:
image

Maybe it has todo with my window manager rules? I dont know, maybe add a rule that puts hudkit at the top?

Thanks.

shell subprocessing + keyboard support? questions

This is an interesting repository as I recently did web development and is into r/unixporn, but I have some questions assuming if this project is still active.

Is there any API or a workaround for subprocessing for getting external information? (active workspace number, filesystem utilizing, dbus utilizing, or powering or rebooting from a powermenu window made with this)

I'm planning to add keyboard support for my powermenu window, but apparently, I saw your pull request about keyboard support, can I utilize it?

At first glance, I felt like this API is a bit lacking, because I feel like it's specifically made for HUDs or status bars to show time, computer performance, etc., unless if this is something made for fun.

Using i3 as my window manager.

multi-display bug and feature request

If I launch the command from the 2nd of two monitors it'll take the overall width of the combined displays and initiate the HUD on the second monitor. This results in the first monitor not having the HUD and the second one displaying a HUD that appears stretched.

feature request) add the ability to only display HUD on default monitor when multiple are present via a command line flag

bug report) HUD incorrectly estimates size and position when not initialized from the first of a multiple display setup.

Research brain-dump: Possible implementation paths for handling input events while also passing them through

As pointed out in #3, Hudkit currently passes through all input events. This is by design, but that's because the design is not ambitious enough. 🔥

If desktop input events could be duplicated to the Hudkit page in addition to the passthrough, that would open up many interactive "applications"—which is to say I really wanna resurrect this ancient hypergurl.com mouse-trailing clock that I thought was cool when I was 12, and I was so disappointed that the page said "This script works on webpages only and cannot be installed to desktops". Now, 15 years of programming later, something is flickering at the end of this tunnel. Maybe.


Notes for possible implementation paths:

  • Can this be done in GDK/GTK only?

    • Is it possible to send synthetic events?
      → ✔️ Yes. gdk_event_new(GDK_KEY_PRESS), gtk_main_do_event. Gist w/ makefile here.

    • Is it possible to capture all input events globally?
      → ❔ Probably not. GDK appears not to consider this sort of generality.

    • Is it possible to cause GdkEvents to be sent to the desktop?
      → ❔ Maybe. The above example Gist only ever sends events to itself, even if I focus a different window before the on_timeout triggers. But maybe there's a low-level alternative to gtk_main_do_event.

  • Can this be done with a combination of X11 and GDK/GTK?

    • Is it possible to capture all input events globally at X11 level (keylogger style) such that they're still delivered to the focused application?
      → ✔️ Yes. I have written such an X11 program.

    • Is it possible to convert XEvents to GdkEvents?
      → ✅ Ostensibly yes; GDK does it internally like this. The function isn't exported to the public interface, but we could pull in GTK sources; they're big (13MiB zipped), but LGPL-licensed. Need to figure out the right compiler incantations, and hopefully not having to compile whole damn GTK with us because nooope.

    • Is it possible to interleave a GTK and X11 event loop, or otherwise coordinate?
      → ✅ Again yeah in principle; GDK must interleave them internally. And could always fork and do it via socket.

    • Is it possible to send a GdkEvent converted from an XEvent directly to a window?
      → ❔ Unsure. I thought gdk_event_put might do that, but the doc's wording of "Appends a copy of the given event onto the front of the event queue for event->any.window’s display" sounds to me like the event will be plopped into the top level queue for this GdkDisplay, before input mask filtering, and then it's just pointless, because it'll be pruned anyhow. But maybe it's worth a try.

If anyone reading knows anything even a little bit related to this, please link!

Compiling with Nix toolchain

Hello, I've been trying to get hudkit compiled on NixOS using the nix toolchain.

More specifically, I've tried the following with no success:

❯ nix-shell --packages pkg-config gtk3 webkitgtk --run make
gcc -std=c11 main.c -o hudkit `pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0`
main.c: In function ‘main’:
main.c:450:32: warning: implicit declaration of function ‘strtok_r’; did you mean ‘strtok’? [-Wimplicit-function-declaration]
  450 |             for (char *entry = strtok_r(
      |                                ^~~~~~~~
      |                                strtok
main.c:450:32: warning: initialization of ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
main.c:450:13: error: declaration of non-variable ‘strtok_r’ in ‘for’ loop initial declaration
  450 |             for (char *entry = strtok_r(
      |             ^~~
main.c:453:27: warning: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
  453 |                     entry = strtok_r(NULL, ",", &strtok_savepoint)) {
      |                           ^
main.c:711:12: error: variable ‘usr1_action’ has initializer but incomplete type
  711 |     struct sigaction usr1_action = {
      |            ^~~~~~~~~
main.c:712:10: error: ‘struct sigaction’ has no member named ‘sa_handler’
  712 |         .sa_handler = on_signal_sigusr1
      |          ^~~~~~~~~~
main.c:712:23: warning: excess elements in struct initializer
  712 |         .sa_handler = on_signal_sigusr1
      |                       ^~~~~~~~~~~~~~~~~
main.c:712:23: note: (near initialization for ‘usr1_action’)
main.c:711:22: error: storage size of ‘usr1_action’ isn’t known
  711 |     struct sigaction usr1_action = {
      |                      ^~~~~~~~~~~
main.c:714:5: warning: implicit declaration of function ‘sigaction’ [-Wimplicit-function-declaration]
  714 |     sigaction(SIGUSR1, &usr1_action, NULL);
      |     ^~~~~~~~~
make: *** [makefile:2: hudkit] Error 1

Do you have any tips on how I might get through this?

Overlay extends off-monitor

After following the instructions on the readme.md and running ./example/run.sh, the overlay shows up but extends incorrectly offscreen. Here is a description of my setup as seen in the attached picture:
Monitor 1 is marked as not primary, it is rotated vertically at 1440x2560. It is to the right of monitor 2.
Monitor 2 is marked as primary, it is 3400x1440. It is to the left of monitor 1.
The first overlay that identifies monitor 2 appears on monitor 1, and since the width on monitor 1 of 1440 is less than 3440, the overlay is cut off. I do not see any overlay for monitor 2, but presumably it is extended even further to the right of monitor 1.
I also cannot click on windows behind the overlays.

Screenshot from 2023-07-04 10-28-24

Hot cool demonstration GIF in the readme

...like https://github.com/progrium/topframe has. 🔥

To demonstrate that parts of the window can be made clickable and that it can really render on top of everything, a neat demo would be an application launcher: Clickable icon in the bottom right, which opens up a large clickable menu for starting programs, with gratuitous RGB flashbang animations to hammer the point home.


I'd just screencap my own hudkit setup, but I'm too minimalist for my own good. This is the top right of my screen:

shot

It looks nice, but it's nowhere near explodey enough to demonstrate hudkit's feature-set fully. 😅

On WSL2: Cannot clickthrough example hud

expected behavior: i should be able to click on stuff through the hud

actual behavior: clicking on things underneath the hud doesn't function. I can click-drag to highlight text displayed on the HUD, however. after a few minutes, or so, a window for "Web Inspector" appears, although it doesn't appear to be clickable, after which the HUD transparent window can be click-dragged off of the screen. there's no associated terminal output, as far as i can tell.

i suspect it may either be an issue with wsl, or an issue with my package manager, tea (tea.xyz), which sometimes messes with PATHs and such.

steps to reproduce: ./run.sh as per the readme, window key to show taskbar, left click to browser window.

environment: Ubuntu 23.04 via WSL2

image

Feedback on using with Linux Mint (mentioning clang in dependencies is necessary?)

If you build on another distro, I'm interested in how it went.

Went grrrreat!

Linux Mint x64 20.1 w/5.8.0-50 kernel.

Dependencies were installed with following commands successfully:

sudo apt-get install libgtk-3-dev
sudo apt-get install libwebkit2gtk-4.0

Make was failing with

clang -std=c11 main.c -o hudkit `pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0`
/bin/sh: 1: clang: not found
make: *** [makefile:2: hudkit] Error 127

Solved with
sudo apt-get install clang
(clang probably should be listed in Dependencies)

run.sh sample script output:
Screenshot from 2021-04-25 14-27-56

Works brilliantly!

The JS API is callback-based; async/await would be prettier

async/await is conciser, and works with try/catch/finally.

  • Do versions of webkit2gtk available on various distros support it?

    (say, Ubuntu, Arch, Fedora)

    → ✔️ Yep. At time of speaking, everybody seems to be on webkit2gtk 2.30.x or 2.31.x, which look like they all support async/await.

  • Does webkit have an implementation for the top-level await TC39 proposal yet?

    Not strictly necessary, but it would be real pretty for documentation purposes not to have to wrap everything (async () => { ... })(), considering a lot of our JS API makes sense to call at the top-level of the file.

    → ❌ Nope. Not yet anyway. Track https://bugs.webkit.org/show_bug.cgi?id=202484.

So: This can be done. I'll get around to it eventually.

Feature request: Recognise keyboard button presses globally, and pass them to addEventListener in page JS

hudkit doesn't seem to recognize when buttons are pressed on the keyboard. Here's a simple test page that should be displaying the keycodes.

<html>
<head></head>
<style>
body {
	background-color: #000;
	font-size: 30px;
	font-weight: bold;
	color: #fff;
}
</style>
<body>
<p id='keyCode'></p>
<script>
document.addEventListener('keydown', function(e) {
	document.getElementById("keyCode").innerHTML = e.keyCode;
});
</script>
</body>
</html>

Continuous integration testing

Ideally, we'd have some sort of automatic test in Travis that starts Xvfb and compton inside that and does some basic pixel reading so I can stop worrying if any of this works after it leaves my PC. 😱

  • Does Travis have Xvfb?

    Yep.

  • Is it possible to even run compton in Xvfb?

    Yes (with +extension COMPOSITE);

    Xvfb +extension COMPOSITE :99 &
    DISPLAY=:99 compton --backend=xrender
    
  • If we do run compton in Xvfb, can we run hudkit in that?

    Yea;

    cd example
    DISPLAY=:99 ./run.sh
    
  • Can we pick a colour out of the Xvfb with something?

    Yas;

    DISPLAY=:99 xwd -root -silent \
      | convert xwd:- -depth 8 -crop "1x1+0+0" txt:- | grep -om1 '#\w\+'
    
  • Does Travis have xwd and convert?

    Yarr; x11-apps contains xwd and imagemagick contains convert, which are both whitelisted.

  • Can we even get a compositor on Travis?

    • Does it have a standalone compositor like compton or xcompmgr?

      → ❌ Nope.

    • What if we overkill it by starting a DE with a built-in compositor?

      → ✔️ Yah. It has Metacity!? wat 😲 ok cool

  • Does it actually work?

    exasperated whisper Noooo.

    triumphant whisper Yeeeeehssss.

multi-monitor support seems to not work

running the example page, sometimes it'll open itself like this:

Screenshot from 2021-04-27 14-38-12

sometimes like this:

Screenshot from 2021-04-27 14-40-13

and other times the window just won't be visible at all.

i'm using i3wm on ubuntu 18.04; i have two 1080p monitors side-by-side:

$ xrandr
Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
DP-0 disconnected (normal left inverted right x axis y axis)
DP-1 disconnected (normal left inverted right x axis y axis)
eDP-1-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 194mm
   1920x1080     60.00*+  59.97    59.96    59.93    48.00  
   1680x1050     59.95    59.88  
   1600x1024     60.17  
   1400x1050     59.98  
   1600x900      59.99    59.94    59.95    59.82  
   1280x1024     60.02  
   1440x900      59.89  
   1400x900      59.96    59.88  
   1280x960      60.00  
   1440x810      60.00    59.97  
   1368x768      59.88    59.85  
   1360x768      59.80    59.96  
   1280x800      59.99    59.97    59.81    59.91  
   1152x864      60.00  
   1280x720      60.00    59.99    59.86    59.74  
   1024x768      60.04    60.00  
   960x720       60.00  
   928x696       60.05  
   896x672       60.01  
   1024x576      59.95    59.96    59.90    59.82  
   960x600       59.93    60.00  
   960x540       59.96    59.99    59.63    59.82  
   800x600       60.00    60.32    56.25  
   840x525       60.01    59.88  
   864x486       59.92    59.57  
   800x512       60.17  
   700x525       59.98  
   800x450       59.95    59.82  
   640x512       60.02  
   720x450       59.89  
   700x450       59.96    59.88  
   640x480       60.00    59.94  
   720x405       59.51    58.99  
   684x384       59.88    59.85  
   680x384       59.80    59.96  
   640x400       59.88    59.98  
   576x432       60.06  
   640x360       59.86    59.83    59.84    59.32  
   512x384       60.00  
   512x288       60.00    59.92  
   480x270       59.63    59.82  
   400x300       60.32    56.34  
   432x243       59.92    59.57  
   320x240       60.05  
   360x202       59.51    59.13  
   320x180       59.84    59.32  
DP-1-1 disconnected (normal left inverted right x axis y axis)
HDMI-1-1 disconnected (normal left inverted right x axis y axis)
HDMI-1-2 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 477mm x 268mm
   1920x1080     60.00*+  59.94  
   1680x1050     59.88  
   1280x1024     75.02    60.02  
   1440x900      59.90  
   1280x960      60.00  
   1280x720      60.00    59.94  
   1024x768      75.03    70.07    60.00  
   832x624       74.55  
   800x600       72.19    75.00    60.32    56.25  
   720x480       60.00    59.94  
   640x480       75.00    72.81    66.67    60.00    59.94  
   720x400       70.08  

presumably this is something weird about my setup, given it sounds like it works for other people...

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.