DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

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

2

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.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay