300 lines
6.0 KiB
Plaintext
300 lines
6.0 KiB
Plaintext
using Gtk 4.0;
|
|
using Adw 1;
|
|
|
|
Adw.StatusPage error_page {
|
|
icon-name: "computer-fail-symbolic";
|
|
title: _("Oh, no.");
|
|
description: _("Unable to acquire an OpenGL context for rendering.");
|
|
|
|
child: LinkButton {
|
|
label: "https://ghostty.org/docs/help/gtk-opengl-context";
|
|
uri: "https://ghostty.org/docs/help/gtk-opengl-context";
|
|
};
|
|
}
|
|
|
|
Overlay terminal_page {
|
|
focusable: false;
|
|
focus-on-click: false;
|
|
|
|
child: Box {
|
|
hexpand: true;
|
|
vexpand: true;
|
|
|
|
GLArea gl_area {
|
|
realize => $gl_realize();
|
|
unrealize => $gl_unrealize();
|
|
render => $gl_render();
|
|
resize => $gl_resize();
|
|
hexpand: true;
|
|
vexpand: true;
|
|
focusable: true;
|
|
focus-on-click: true;
|
|
has-stencil-buffer: false;
|
|
has-depth-buffer: false;
|
|
allowed-apis: gl;
|
|
}
|
|
|
|
PopoverMenu context_menu {
|
|
closed => $context_menu_closed();
|
|
menu-model: context_menu_model;
|
|
flags: nested;
|
|
halign: start;
|
|
has-arrow: false;
|
|
}
|
|
};
|
|
|
|
[overlay]
|
|
ProgressBar progress_bar_overlay {
|
|
styles [
|
|
"osd",
|
|
]
|
|
|
|
visible: false;
|
|
halign: fill;
|
|
valign: start;
|
|
}
|
|
|
|
[overlay]
|
|
// The "border" bell feature is implemented here as an overlay rather than
|
|
// just adding a border to the GLArea or other widget for two reasons.
|
|
// First, adding a border to an existing widget causes a resize of the
|
|
// widget which undesirable side effects. Second, we can make it reactive
|
|
// here in the blueprint with relatively little code.
|
|
Revealer {
|
|
reveal-child: bind $should_border_be_shown(template.config, template.bell-ringing) as <bool>;
|
|
transition-type: crossfade;
|
|
transition-duration: 500;
|
|
|
|
Box bell_overlay {
|
|
styles [
|
|
"bell-overlay",
|
|
]
|
|
|
|
halign: fill;
|
|
valign: fill;
|
|
}
|
|
}
|
|
|
|
[overlay]
|
|
$GhosttySurfaceChildExited child_exited_overlay {
|
|
visible: bind template.child-exited;
|
|
close-request => $child_exited_close();
|
|
}
|
|
|
|
[overlay]
|
|
$GhosttyResizeOverlay resize_overlay {}
|
|
|
|
[overlay]
|
|
Label url_left {
|
|
styles [
|
|
"background",
|
|
"url-overlay",
|
|
]
|
|
|
|
visible: false;
|
|
halign: start;
|
|
valign: end;
|
|
label: bind template.mouse-hover-url;
|
|
|
|
EventControllerMotion url_ec_motion {
|
|
enter => $url_mouse_enter();
|
|
leave => $url_mouse_leave();
|
|
}
|
|
}
|
|
|
|
[overlay]
|
|
Label url_right {
|
|
styles [
|
|
"background",
|
|
"url-overlay",
|
|
]
|
|
|
|
visible: false;
|
|
halign: end;
|
|
valign: end;
|
|
label: bind template.mouse-hover-url;
|
|
}
|
|
|
|
[overlay]
|
|
// Apply unfocused-split-fill and unfocused-split-opacity to current surface
|
|
// this is only applied when a tab has more than one surface
|
|
Revealer {
|
|
reveal-child: bind $should_unfocused_split_be_shown(template.unfocused-split) as <bool>;
|
|
transition-duration: 0;
|
|
DrawingArea {
|
|
styles [
|
|
"unfocused-split",
|
|
]
|
|
}
|
|
}
|
|
|
|
// Event controllers for interactivity
|
|
EventControllerFocus {
|
|
enter => $focus_enter();
|
|
leave => $focus_leave();
|
|
}
|
|
|
|
EventControllerKey {
|
|
key-pressed => $key_pressed();
|
|
key-released => $key_released();
|
|
}
|
|
|
|
EventControllerMotion {
|
|
motion => $mouse_motion();
|
|
leave => $mouse_leave();
|
|
}
|
|
|
|
EventControllerScroll {
|
|
scroll => $scroll();
|
|
scroll-begin => $scroll_begin();
|
|
scroll-end => $scroll_end();
|
|
flags: both_axes;
|
|
}
|
|
|
|
GestureClick {
|
|
pressed => $mouse_down();
|
|
released => $mouse_up();
|
|
button: 0;
|
|
}
|
|
|
|
DropTarget drop_target {
|
|
drop => $drop();
|
|
actions: copy;
|
|
}
|
|
}
|
|
|
|
template $GhosttySurface: Adw.Bin {
|
|
styles [
|
|
"surface",
|
|
]
|
|
|
|
notify::bell-ringing => $notify_bell_ringing();
|
|
notify::config => $notify_config();
|
|
notify::error => $notify_error();
|
|
notify::mouse-hover-url => $notify_mouse_hover_url();
|
|
notify::mouse-hidden => $notify_mouse_hidden();
|
|
notify::mouse-shape => $notify_mouse_shape();
|
|
// Some history: we used to use a Stack here and swap between the
|
|
// terminal and error pages as needed. But a Stack doesn't play nice
|
|
// with our SplitTree and Gtk.Paned usage[^1]. Replacing this with
|
|
// a manual programmatic child swap fixed this. So if you ever change
|
|
// this, be sure to test many splits!
|
|
//
|
|
// [^1]: https://github.com/ghostty-org/ghostty/issues/8533
|
|
child: terminal_page;
|
|
}
|
|
|
|
IMMulticontext im_context {
|
|
input-purpose: terminal;
|
|
preedit-start => $im_preedit_start();
|
|
preedit-changed => $im_preedit_changed();
|
|
preedit-end => $im_preedit_end();
|
|
commit => $im_commit();
|
|
}
|
|
|
|
menu context_menu_model {
|
|
section {
|
|
item {
|
|
label: _("Copy");
|
|
action: "win.copy";
|
|
}
|
|
|
|
item {
|
|
label: _("Paste");
|
|
action: "win.paste";
|
|
}
|
|
}
|
|
|
|
section {
|
|
item {
|
|
label: _("Clear");
|
|
action: "win.clear";
|
|
}
|
|
|
|
item {
|
|
label: _("Reset");
|
|
action: "win.reset";
|
|
}
|
|
}
|
|
|
|
section {
|
|
submenu {
|
|
label: _("Split");
|
|
|
|
item {
|
|
label: _("Change Title…");
|
|
action: "surface.prompt-title";
|
|
}
|
|
|
|
item {
|
|
label: _("Split Up");
|
|
action: "split-tree.new-split";
|
|
target: "up";
|
|
}
|
|
|
|
item {
|
|
label: _("Split Down");
|
|
action: "split-tree.new-split";
|
|
target: "down";
|
|
}
|
|
|
|
item {
|
|
label: _("Split Left");
|
|
action: "split-tree.new-split";
|
|
target: "left";
|
|
}
|
|
|
|
item {
|
|
label: _("Split Right");
|
|
action: "split-tree.new-split";
|
|
target: "right";
|
|
}
|
|
}
|
|
|
|
submenu {
|
|
label: _("Tab");
|
|
|
|
item {
|
|
label: _("New Tab");
|
|
action: "win.new-tab";
|
|
}
|
|
|
|
item {
|
|
label: _("Close Tab");
|
|
action: "tab.close";
|
|
target: "this";
|
|
}
|
|
}
|
|
|
|
submenu {
|
|
label: _("Window");
|
|
|
|
item {
|
|
label: _("New Window");
|
|
action: "win.new-window";
|
|
}
|
|
|
|
item {
|
|
label: _("Close Window");
|
|
action: "win.close";
|
|
}
|
|
}
|
|
}
|
|
|
|
section {
|
|
submenu {
|
|
label: _("Config");
|
|
|
|
item {
|
|
label: _("Open Configuration");
|
|
action: "app.open-config";
|
|
}
|
|
|
|
item {
|
|
label: _("Reload Configuration");
|
|
action: "app.reload-config";
|
|
}
|
|
}
|
|
}
|
|
}
|