DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

Posted on • Edited on • Originally published at polv.cc

Maximize (not fullscreen) your cross-platform desktop application

If not for macOS "fullscreen" (and some Linux), it wouldn't be a pain.

I have realize the solution for a while, with Golang and Lorca. Nonetheless, it uses cgo.

package main

import (
    "fmt"
    "log"

    /*
        #cgo darwin LDFLAGS: -framework CoreGraphics

        #if defined(__APPLE__)
        #include <CoreGraphics/CGDisplayConfiguration.h>
        int display_width() {
        return CGDisplayPixelsWide(CGMainDisplayID());
        }
        int display_height() {
        return CGDisplayPixelsHigh(CGMainDisplayID());
        }
        #else
        int display_width() {
        return 0;
        }
        int display_height() {
        return 0;
        }
        #endif
    */
    "C"

    "github.com/zserge/lorca"
)

func main() {
    if lorca.LocateChrome() == "" {
        lorca.PromptDownload()
        log.Fatal(fmt.Errorf("cannot open outside Chrome desktop application"))
    } else {
        width := int(C.display_width())
        height := int(C.display_height())

        if width == 0 || height == 0 {
            width = 1024
            height = 768
        }

        w, err := lorca.New("https://example.com", "", width, height)
        if err != nil {
            log.Fatal(err)
        }

        defer w.Close()

        // This does nothing in macOS, BTW.
        w.SetBounds(lorca.Bounds{
            WindowState: lorca.WindowStateMaximized,
        })

        <-w.Done()
    }
}
Enter fullscreen mode Exit fullscreen mode

Then, you can cross-compile for all major platforms using xgo.

BRANCH=${<BRANCH_NAME>:-"master"}
REPO=<REPO_NAME>

$(go env GOPATH)/bin/xgo \
  -ldflags="-H windowsgui" \
  -branch=BRANCH \
  -targets=windows/* \
  REPO

if [[ $(go env GOOS) == 'darwin' ]]; then
  go build "${PWD##*/}.app"
  $(go env GOPATH)/bin/xgo \
    -branch=BRANCH \
    -targets=linux/* \
    REPO
else
  $(go env GOPATH)/bin/xgo \
    -branch=BRANCH \
    -targets=linux/*,darwin/amd64 \
    REPO

  rm *-darwin*.app
  for f in *-darwin*; do mv "$f" "$f.app"; done
fi
Enter fullscreen mode Exit fullscreen mode

The question still remains. What if I don't use Lorca, Chrome DevTools Protocol, or any other frameworks with built-in maximize, so what should I do? (BTW, Electron has built-in maximization, but webview/webview and Neutralino.js don't have one...)

I have an approximate answer in cgo.

import (
    "runtime"

    /*
       #cgo darwin LDFLAGS: -framework CoreGraphics
       #cgo linux pkg-config: x11

       #if defined(__APPLE__)
       #include <CoreGraphics/CGDisplayConfiguration.h>
       int display_width() {
        return CGDisplayPixelsWide(CGMainDisplayID());
       }
       int display_height() {
        return CGDisplayPixelsHigh(CGMainDisplayID());
       }
       #elif defined(_WIN32)
       #include <wtypes.h>
       int display_width() {
        RECT desktop;
        const HWND hDesktop = GetDesktopWindow();
        GetWindowRect(hDesktop, &desktop);
        return desktop.right;
       }
       int display_height() {
        RECT desktop;
        const HWND hDesktop = GetDesktopWindow();
        GetWindowRect(hDesktop, &desktop);
        return desktop.bottom;
       }
       #else
       #include <X11/Xlib.h>
       int display_width() {
        Display* d = XOpenDisplay(NULL);
        Screen*  s = DefaultScreenOfDisplay(d);
        return s->width;
       }
       int display_height() {
        Display* d = XOpenDisplay(NULL);
        Screen*  s = DefaultScreenOfDisplay(d);
        return s->height;
       }
       #endif
    */
    "C"
)

func getFullscreenSize() (int, int) {
    width := int(C.display_width())
    height := int(C.display_height())

    // Current method of getting screen size in linux and windows makes it fall offscreen
    if runtime.GOOS == "linux" || runtime.GOOS == "windows" {
        width = width - 50
        height = height - 100
    }

    if width == 0 || height == 0 {
        width = 1024
        height = 768
    }

    return width, height
}
Enter fullscreen mode Exit fullscreen mode

Not really fullscreen in Windows and Linux. Also, when compiling for Linux, you cannot use xgo -- I use Docker instead.

ARG ARCH=""
FROM ${ARCH}debian
RUN apt-get update
RUN apt-get install -y --no-install-recommends build-essential 
RUN apt-get install -y xorg-dev
RUN apt-get install -y golang git
Enter fullscreen mode Exit fullscreen mode

And,

for arch in amd64 i386
  do
    docker build --build-arg ARCH=$arch/ -t ${PWD##*/}-$arch .
  done

for arch in amd64 i386
  do
    docker run --rm -v \
      "$PWD":/usr/app \
      -w /usr/app \
      ${PWD##*/}-$arch \
      go build -o "${PWD##*/}-$arch"
  done
Enter fullscreen mode Exit fullscreen mode

BTW, I've just found docker xbuild.

Top comments (0)