mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
apprt/gtk-ng: move overlays and event controllers into Blueprint
I became far less stupid and figured out how to figure this out by reading the source code and since then I've been enlightened and can clean up our Blueprints quite a bit. Yay!
This commit is contained in:
@ -247,18 +247,26 @@ pub const Surface = extern struct {
|
|||||||
|
|
||||||
/// The overlay we use for things such as the URL hover label
|
/// The overlay we use for things such as the URL hover label
|
||||||
/// or resize box. Bound from the template.
|
/// or resize box. Bound from the template.
|
||||||
overlay: *gtk.Overlay = undefined,
|
overlay: *gtk.Overlay,
|
||||||
|
|
||||||
/// The GLAarea that renders the actual surface. This is a binding
|
/// The GLAarea that renders the actual surface. This is a binding
|
||||||
/// to the template so it doesn't have to be unrefed manually.
|
/// to the template so it doesn't have to be unrefed manually.
|
||||||
gl_area: *gtk.GLArea = undefined,
|
gl_area: *gtk.GLArea,
|
||||||
|
|
||||||
/// The labels for the left/right sides of the URL hover tooltip.
|
/// The labels for the left/right sides of the URL hover tooltip.
|
||||||
url_left: *gtk.Label = undefined,
|
url_left: *gtk.Label,
|
||||||
url_right: *gtk.Label = undefined,
|
url_right: *gtk.Label,
|
||||||
|
url_ec_motion: *gtk.EventControllerMotion,
|
||||||
|
|
||||||
/// The resize overlay
|
/// The resize overlay
|
||||||
resize_overlay: *ResizeOverlay = undefined,
|
resize_overlay: *ResizeOverlay,
|
||||||
|
|
||||||
|
// Event controllers
|
||||||
|
ec_focus: *gtk.EventControllerFocus,
|
||||||
|
ec_key: *gtk.EventControllerKey,
|
||||||
|
ec_motion: *gtk.EventControllerMotion,
|
||||||
|
ec_scroll: *gtk.EventControllerScroll,
|
||||||
|
gesture_click: *gtk.GestureClick,
|
||||||
|
|
||||||
/// The apprt Surface.
|
/// The apprt Surface.
|
||||||
rt_surface: ApprtSurface = undefined,
|
rt_surface: ApprtSurface = undefined,
|
||||||
@ -795,22 +803,16 @@ pub const Surface = extern struct {
|
|||||||
priv.config = app.getConfig();
|
priv.config = app.getConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
const self_widget = self.as(gtk.Widget);
|
|
||||||
|
|
||||||
// Setup our event controllers to get input events
|
// Setup our event controllers to get input events
|
||||||
const ec_key = gtk.EventControllerKey.new();
|
|
||||||
errdefer ec_key.unref();
|
|
||||||
self_widget.addController(ec_key.as(gtk.EventController));
|
|
||||||
errdefer self_widget.removeController(ec_key.as(gtk.EventController));
|
|
||||||
_ = gtk.EventControllerKey.signals.key_pressed.connect(
|
_ = gtk.EventControllerKey.signals.key_pressed.connect(
|
||||||
ec_key,
|
priv.ec_key,
|
||||||
*Self,
|
*Self,
|
||||||
ecKeyPressed,
|
ecKeyPressed,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.EventControllerKey.signals.key_released.connect(
|
_ = gtk.EventControllerKey.signals.key_released.connect(
|
||||||
ec_key,
|
priv.ec_key,
|
||||||
*Self,
|
*Self,
|
||||||
ecKeyReleased,
|
ecKeyReleased,
|
||||||
self,
|
self,
|
||||||
@ -818,19 +820,15 @@ pub const Surface = extern struct {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Focus controller will tell us about focus enter/exit events
|
// Focus controller will tell us about focus enter/exit events
|
||||||
const ec_focus = gtk.EventControllerFocus.new();
|
|
||||||
errdefer ec_focus.unref();
|
|
||||||
self_widget.addController(ec_focus.as(gtk.EventController));
|
|
||||||
errdefer self_widget.removeController(ec_focus.as(gtk.EventController));
|
|
||||||
_ = gtk.EventControllerFocus.signals.enter.connect(
|
_ = gtk.EventControllerFocus.signals.enter.connect(
|
||||||
ec_focus,
|
priv.ec_focus,
|
||||||
*Self,
|
*Self,
|
||||||
ecFocusEnter,
|
ecFocusEnter,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.EventControllerFocus.signals.leave.connect(
|
_ = gtk.EventControllerFocus.signals.leave.connect(
|
||||||
ec_focus,
|
priv.ec_focus,
|
||||||
*Self,
|
*Self,
|
||||||
ecFocusLeave,
|
ecFocusLeave,
|
||||||
self,
|
self,
|
||||||
@ -838,20 +836,15 @@ pub const Surface = extern struct {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Clicks
|
// Clicks
|
||||||
const gesture_click = gtk.GestureClick.new();
|
|
||||||
errdefer gesture_click.unref();
|
|
||||||
gesture_click.as(gtk.GestureSingle).setButton(0);
|
|
||||||
self_widget.addController(gesture_click.as(gtk.EventController));
|
|
||||||
errdefer self_widget.removeController(gesture_click.as(gtk.EventController));
|
|
||||||
_ = gtk.GestureClick.signals.pressed.connect(
|
_ = gtk.GestureClick.signals.pressed.connect(
|
||||||
gesture_click,
|
priv.gesture_click,
|
||||||
*Self,
|
*Self,
|
||||||
gcMouseDown,
|
gcMouseDown,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.GestureClick.signals.released.connect(
|
_ = gtk.GestureClick.signals.released.connect(
|
||||||
gesture_click,
|
priv.gesture_click,
|
||||||
*Self,
|
*Self,
|
||||||
gcMouseUp,
|
gcMouseUp,
|
||||||
self,
|
self,
|
||||||
@ -859,19 +852,15 @@ pub const Surface = extern struct {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Mouse movement
|
// Mouse movement
|
||||||
const ec_motion = gtk.EventControllerMotion.new();
|
|
||||||
errdefer ec_motion.unref();
|
|
||||||
self_widget.addController(ec_motion.as(gtk.EventController));
|
|
||||||
errdefer self_widget.removeController(ec_motion.as(gtk.EventController));
|
|
||||||
_ = gtk.EventControllerMotion.signals.motion.connect(
|
_ = gtk.EventControllerMotion.signals.motion.connect(
|
||||||
ec_motion,
|
priv.ec_motion,
|
||||||
*Self,
|
*Self,
|
||||||
ecMouseMotion,
|
ecMouseMotion,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.EventControllerMotion.signals.leave.connect(
|
_ = gtk.EventControllerMotion.signals.leave.connect(
|
||||||
ec_motion,
|
priv.ec_motion,
|
||||||
*Self,
|
*Self,
|
||||||
ecMouseLeave,
|
ecMouseLeave,
|
||||||
self,
|
self,
|
||||||
@ -879,26 +868,22 @@ pub const Surface = extern struct {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Scroll
|
// Scroll
|
||||||
const ec_scroll = gtk.EventControllerScroll.new(.flags_both_axes);
|
|
||||||
errdefer ec_scroll.unref();
|
|
||||||
self_widget.addController(ec_scroll.as(gtk.EventController));
|
|
||||||
errdefer self_widget.removeController(ec_scroll.as(gtk.EventController));
|
|
||||||
_ = gtk.EventControllerScroll.signals.scroll.connect(
|
_ = gtk.EventControllerScroll.signals.scroll.connect(
|
||||||
ec_scroll,
|
priv.ec_scroll,
|
||||||
*Self,
|
*Self,
|
||||||
ecMouseScroll,
|
ecMouseScroll,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.EventControllerScroll.signals.scroll_begin.connect(
|
_ = gtk.EventControllerScroll.signals.scroll_begin.connect(
|
||||||
ec_scroll,
|
priv.ec_scroll,
|
||||||
*Self,
|
*Self,
|
||||||
ecMouseScrollPrecisionBegin,
|
ecMouseScrollPrecisionBegin,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.EventControllerScroll.signals.scroll_end.connect(
|
_ = gtk.EventControllerScroll.signals.scroll_end.connect(
|
||||||
ec_scroll,
|
priv.ec_scroll,
|
||||||
*Self,
|
*Self,
|
||||||
ecMouseScrollPrecisionEnd,
|
ecMouseScrollPrecisionEnd,
|
||||||
self,
|
self,
|
||||||
@ -1014,43 +999,25 @@ pub const Surface = extern struct {
|
|||||||
|
|
||||||
// Some other initialization steps
|
// Some other initialization steps
|
||||||
self.initUrlOverlay();
|
self.initUrlOverlay();
|
||||||
self.initResizeOverlay();
|
|
||||||
|
|
||||||
// Initialize our config
|
// Initialize our config
|
||||||
self.propConfig(undefined, null);
|
self.propConfig(undefined, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initResizeOverlay(self: *Self) void {
|
|
||||||
const priv = self.private();
|
|
||||||
const overlay = priv.overlay;
|
|
||||||
overlay.addOverlay(priv.resize_overlay.as(gtk.Widget));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn initUrlOverlay(self: *Self) void {
|
fn initUrlOverlay(self: *Self) void {
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
const overlay = priv.overlay;
|
|
||||||
const url_left = priv.url_left.as(gtk.Widget);
|
|
||||||
const url_right = priv.url_right.as(gtk.Widget);
|
|
||||||
|
|
||||||
// Add the url label to the overlay
|
|
||||||
overlay.addOverlay(url_left);
|
|
||||||
overlay.addOverlay(url_right);
|
|
||||||
|
|
||||||
// Setup a motion controller to handle moving the label
|
// Setup a motion controller to handle moving the label
|
||||||
// to avoid the mouse.
|
// to avoid the mouse.
|
||||||
const ec_motion = gtk.EventControllerMotion.new();
|
|
||||||
errdefer ec_motion.unref();
|
|
||||||
url_left.addController(ec_motion.as(gtk.EventController));
|
|
||||||
errdefer url_left.removeController(ec_motion.as(gtk.EventController));
|
|
||||||
_ = gtk.EventControllerMotion.signals.enter.connect(
|
_ = gtk.EventControllerMotion.signals.enter.connect(
|
||||||
ec_motion,
|
priv.url_ec_motion,
|
||||||
*Self,
|
*Self,
|
||||||
ecUrlMouseEnter,
|
ecUrlMouseEnter,
|
||||||
self,
|
self,
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
_ = gtk.EventControllerMotion.signals.leave.connect(
|
_ = gtk.EventControllerMotion.signals.leave.connect(
|
||||||
ec_motion,
|
priv.url_ec_motion,
|
||||||
*Self,
|
*Self,
|
||||||
ecUrlMouseLeave,
|
ecUrlMouseLeave,
|
||||||
self,
|
self,
|
||||||
@ -1938,6 +1905,24 @@ pub const Surface = extern struct {
|
|||||||
class.bindTemplateChildPrivate("url_right", .{});
|
class.bindTemplateChildPrivate("url_right", .{});
|
||||||
class.bindTemplateChildPrivate("resize_overlay", .{});
|
class.bindTemplateChildPrivate("resize_overlay", .{});
|
||||||
|
|
||||||
|
// EventControllers don't work with our helper.
|
||||||
|
// https://github.com/ianprime0509/zig-gobject/issues/111
|
||||||
|
inline for (&.{
|
||||||
|
"ec_focus",
|
||||||
|
"ec_key",
|
||||||
|
"ec_motion",
|
||||||
|
"ec_scroll",
|
||||||
|
"gesture_click",
|
||||||
|
"url_ec_motion",
|
||||||
|
}) |name| {
|
||||||
|
gtk.Widget.Class.bindTemplateChildFull(
|
||||||
|
gobject.ext.as(gtk.Widget.Class, class),
|
||||||
|
name,
|
||||||
|
@intFromBool(false),
|
||||||
|
Private.offset + @offsetOf(Private, name),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
gobject.ext.registerProperties(class, &.{
|
gobject.ext.registerProperties(class, &.{
|
||||||
properties.config.impl,
|
properties.config.impl,
|
||||||
|
@ -16,35 +16,52 @@ template $GhosttySurface: Adw.Bin {
|
|||||||
focusable: true;
|
focusable: true;
|
||||||
focus-on-click: true;
|
focus-on-click: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[overlay]
|
||||||
|
$GhosttyResizeOverlay resize_overlay {
|
||||||
|
styles [
|
||||||
|
"size-overlay",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
[overlay]
|
||||||
|
Label url_left {
|
||||||
|
styles [
|
||||||
|
"url-overlay",
|
||||||
|
]
|
||||||
|
|
||||||
|
visible: false;
|
||||||
|
halign: start;
|
||||||
|
valign: end;
|
||||||
|
label: bind template.mouse-hover-url;
|
||||||
|
|
||||||
|
EventControllerMotion url_ec_motion {}
|
||||||
|
}
|
||||||
|
|
||||||
|
[overlay]
|
||||||
|
Label url_right {
|
||||||
|
styles [
|
||||||
|
"url-overlay",
|
||||||
|
]
|
||||||
|
|
||||||
|
visible: false;
|
||||||
|
halign: end;
|
||||||
|
valign: end;
|
||||||
|
label: bind template.mouse-hover-url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Event controllers for interactivity
|
||||||
// The label that shows the currently hovered URL.
|
EventControllerFocus ec_focus {}
|
||||||
Label url_left {
|
|
||||||
styles [
|
EventControllerKey ec_key {}
|
||||||
"url-overlay",
|
|
||||||
]
|
EventControllerMotion ec_motion {}
|
||||||
|
|
||||||
visible: false;
|
EventControllerScroll ec_scroll {}
|
||||||
halign: start;
|
|
||||||
valign: end;
|
GestureClick gesture_click {
|
||||||
label: bind template.mouse-hover-url;
|
button: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Label url_right {
|
|
||||||
styles [
|
|
||||||
"url-overlay",
|
|
||||||
]
|
|
||||||
|
|
||||||
visible: false;
|
|
||||||
halign: end;
|
|
||||||
valign: end;
|
|
||||||
label: bind template.mouse-hover-url;
|
|
||||||
}
|
|
||||||
|
|
||||||
$GhosttyResizeOverlay resize_overlay {
|
|
||||||
styles [
|
|
||||||
"size-overlay",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,8 @@ using Gtk 4.0;
|
|||||||
using Adw 1;
|
using Adw 1;
|
||||||
|
|
||||||
template $GhosttyWindow: Adw.ApplicationWindow {
|
template $GhosttyWindow: Adw.ApplicationWindow {
|
||||||
|
default-width: 800;
|
||||||
|
default-height: 600;
|
||||||
|
|
||||||
content: $GhosttySurface surface {};
|
content: $GhosttySurface surface {};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user