131 lines
5.7 KiB
C++
131 lines
5.7 KiB
C++
#include <cstdio>
|
|
|
|
#include <QApplication>
|
|
#include <QCoreApplication>
|
|
#include <QIcon>
|
|
#include <QSurfaceFormat>
|
|
|
|
#include "GlobalShortcuts.h"
|
|
#include "MainWindow.h"
|
|
#include "ghostty.h"
|
|
|
|
// True when any argv entry starts with `+` — i.e. the user invoked a
|
|
// libghostty CLI action (`+show-config`, `+list-fonts`, `+version`, …).
|
|
// We detect early so the CLI path can run without paying the cost of
|
|
// constructing a QApplication (which opens a Wayland/X11 connection
|
|
// only to exit).
|
|
static bool isCliActionInvocation(int argc, char **argv) {
|
|
for (int i = 1; i < argc; ++i) {
|
|
if (argv[i] && argv[i][0] == '+') return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
// CLI action fast path: skip Qt entirely. ghostty_init parses argv
|
|
// for the `+action`; ghostty_cli_try_action runs it and exits the
|
|
// process. If something fails (unknown action, multiple actions),
|
|
// ghostty_init returns non-zero and we surface the same help hint
|
|
// macOS does.
|
|
if (isCliActionInvocation(argc, argv)) {
|
|
if (ghostty_init(static_cast<uintptr_t>(argc), argv) != GHOSTTY_SUCCESS) {
|
|
std::fprintf(
|
|
stderr,
|
|
"Ghastty failed to initialize! If you're executing Ghastty from\n"
|
|
"the command line then this is usually because an invalid action\n"
|
|
"or multiple actions were specified. Actions start with the `+`\n"
|
|
"character.\n\n"
|
|
"View all available actions by running `ghastty +help`.\n");
|
|
return 1;
|
|
}
|
|
ghostty_cli_try_action();
|
|
// ghostty_cli_try_action exits the process when an action ran; if
|
|
// it returned, no `+action` was actually parseable from argv —
|
|
// bail out rather than fall through to the GUI with leftover
|
|
// junk in argv.
|
|
std::fprintf(stderr, "[ghastty] no CLI action ran; aborting\n");
|
|
return 1;
|
|
}
|
|
|
|
// Use the display's true fractional scale rather than rounding it up
|
|
// (Wayland otherwise reports e.g. 2.0 for a 1.2x display, which scales
|
|
// the terminal up).
|
|
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
|
|
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
|
|
|
// Multiple GL surfaces compose reliably with a shared GL context.
|
|
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
|
|
|
// Ghostty's OpenGL renderer requires at least OpenGL 4.3 core.
|
|
QSurfaceFormat fmt;
|
|
fmt.setRenderableType(QSurfaceFormat::OpenGL);
|
|
fmt.setProfile(QSurfaceFormat::CoreProfile);
|
|
fmt.setVersion(4, 3);
|
|
fmt.setAlphaBufferSize(8); // allow a translucent terminal background
|
|
QSurfaceFormat::setDefaultFormat(fmt);
|
|
|
|
QApplication app(argc, argv);
|
|
|
|
// QSettings storage path keys: applicationName + organizationName.
|
|
// Used by the inspector window's geometry autosave (and any future
|
|
// QSettings-backed UI state) — the keys go to
|
|
// ~/.config/ghastty/ghastty.conf. We pass the same string to both
|
|
// because we don't run a multi-app suite under a parent
|
|
// organization.
|
|
QCoreApplication::setApplicationName(QStringLiteral("ghastty"));
|
|
QCoreApplication::setOrganizationName(QStringLiteral("ghastty"));
|
|
|
|
// Match the installed ghastty.desktop: this becomes the Wayland app-id
|
|
// (and X11 WM_CLASS), so the compositor associates the window with the
|
|
// desktop entry — taskbar icon, launcher identity.
|
|
QGuiApplication::setDesktopFileName(QStringLiteral("ghastty"));
|
|
|
|
// The window icon, embedded so it works even running from the build
|
|
// tree (when ghastty.desktop / the icon theme are not yet installed).
|
|
QGuiApplication::setWindowIcon(QIcon(QStringLiteral(":/ghastty.svg")));
|
|
|
|
// We keep the user's system widget style rather than forcing Fusion.
|
|
// Some styles dim and blur translucent windows, which masks the
|
|
// terminal's own background-opacity: Kvantum themes do this when
|
|
// `blurring`/`reduce_window_opacity` are set. The fix belongs in the
|
|
// style's config, not here — for Kvantum, add "ghostty" to the
|
|
// theme's `opaque` app list (the same opt-out video players use).
|
|
|
|
// ghostty_init must run *after* QApplication: QApplication strips its
|
|
// own options (e.g. -style) out of argv in place, and libghostty later
|
|
// re-scans that array for CLI config — scanning the pre-strip array
|
|
// would walk past its end into freed/null entries. The CLI-action
|
|
// fast path above already initialised libghostty for `+action`
|
|
// invocations and exited; everything reaching here is a GUI launch.
|
|
if (ghostty_init(static_cast<uintptr_t>(argc), argv) != GHOSTTY_SUCCESS) {
|
|
std::fprintf(stderr,
|
|
"[ghastty] ghostty_init failed; check `ghastty +help`\n");
|
|
return 1;
|
|
}
|
|
|
|
// initial-window: when false, start headless (no window mapped at
|
|
// launch). Combined with quit-after-last-window-closed=false this
|
|
// is how a user runs ghastty as a daemon for the global quick-
|
|
// terminal shortcut. The first MainWindow::newWindow internally
|
|
// checks the config and skips show() — so the libghostty app +
|
|
// config still get built, but no QWindow ever appears.
|
|
if (!MainWindow::newWindow(nullptr)) {
|
|
std::fprintf(stderr, "[ghastty] window initialization failed\n");
|
|
return 1;
|
|
}
|
|
|
|
// Register global shortcuts via the XDG portal so the quick terminal
|
|
// can be toggled while Ghostty is unfocused. Keys are assigned by the
|
|
// desktop (KDE System Settings -> Shortcuts).
|
|
GlobalShortcuts globalShortcuts;
|
|
QObject::connect(&globalShortcuts, &GlobalShortcuts::activated,
|
|
[](const QString &id) {
|
|
if (id == QLatin1String("toggle-quick-terminal"))
|
|
MainWindow::toggleQuickTerminal();
|
|
else if (id == QLatin1String("toggle-visibility"))
|
|
MainWindow::toggleVisibility();
|
|
});
|
|
|
|
return app.exec();
|
|
}
|