mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt/embedded: new_window can be called without a parent
This commit is contained in:
@ -78,6 +78,12 @@ class TerminalManager {
|
|||||||
window.toggleFullScreen(nil)
|
window.toggleFullScreen(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If our app isn't active, we make it active. All new_window actions
|
||||||
|
// force our app to be active.
|
||||||
|
if !NSApp.isActive {
|
||||||
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
|
}
|
||||||
|
|
||||||
// We're dispatching this async because otherwise the lastCascadePoint doesn't
|
// We're dispatching this async because otherwise the lastCascadePoint doesn't
|
||||||
// take effect. Our best theory is there is some next-event-loop-tick logic
|
// take effect. Our best theory is there is some next-event-loop-tick logic
|
||||||
// that Cocoa is doing that we need to be after.
|
// that Cocoa is doing that we need to be after.
|
||||||
|
@ -631,7 +631,11 @@ extension Ghostty {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func newWindow(_ userdata: UnsafeMutableRawPointer?, config: ghostty_surface_config_s) {
|
static func newWindow(_ userdata: UnsafeMutableRawPointer?, config: ghostty_surface_config_s) {
|
||||||
let surface = self.surfaceUserdata(from: userdata)
|
let surface: SurfaceView? = if let userdata {
|
||||||
|
self.surfaceUserdata(from: userdata)
|
||||||
|
} else {
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
|
||||||
NotificationCenter.default.post(
|
NotificationCenter.default.post(
|
||||||
name: Notification.ghosttyNewWindow,
|
name: Notification.ghosttyNewWindow,
|
||||||
|
@ -317,6 +317,7 @@ pub fn performAction(
|
|||||||
.unbind => unreachable,
|
.unbind => unreachable,
|
||||||
.ignore => {},
|
.ignore => {},
|
||||||
.quit => try self.setQuit(),
|
.quit => try self.setQuit(),
|
||||||
|
.new_window => try self.newWindow(rt_app, .{ .parent = null }),
|
||||||
.open_config => try self.openConfig(rt_app),
|
.open_config => try self.openConfig(rt_app),
|
||||||
.reload_config => try self.reloadConfig(rt_app),
|
.reload_config => try self.reloadConfig(rt_app),
|
||||||
.close_all_windows => {
|
.close_all_windows => {
|
||||||
|
@ -3416,19 +3416,22 @@ fn showMouse(self: *Surface) void {
|
|||||||
/// will ever return false. We can expand this in the future if it becomes
|
/// will ever return false. We can expand this in the future if it becomes
|
||||||
/// useful. We did previous/next tab so we could implement #498.
|
/// useful. We did previous/next tab so we could implement #498.
|
||||||
pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool {
|
pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool {
|
||||||
// Handle app-scoped bindings by sending it to the app.
|
// Forward app-scoped actions to the app. Some app-scoped actions are
|
||||||
switch (action.scope()) {
|
// special-cased here because they do some special things when performed
|
||||||
.app => {
|
// from the surface.
|
||||||
try self.app.performAction(
|
if (action.scoped(.app)) |app_action| {
|
||||||
|
switch (app_action) {
|
||||||
|
.new_window => try self.app.newWindow(
|
||||||
|
self.rt_app,
|
||||||
|
.{ .parent = self },
|
||||||
|
),
|
||||||
|
|
||||||
|
else => try self.app.performAction(
|
||||||
self.rt_app,
|
self.rt_app,
|
||||||
action.scoped(.app).?,
|
action.scoped(.app).?,
|
||||||
);
|
),
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
|
||||||
|
|
||||||
// Surface fallthrough and handle
|
|
||||||
.surface => {},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (action.scoped(.surface).?) {
|
switch (action.scoped(.surface).?) {
|
||||||
@ -3653,8 +3656,6 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
|
|||||||
v,
|
v,
|
||||||
),
|
),
|
||||||
|
|
||||||
.new_window => try self.app.newWindow(self.rt_app, .{ .parent = self }),
|
|
||||||
|
|
||||||
.new_tab => {
|
.new_tab => {
|
||||||
if (@hasDecl(apprt.Surface, "newTab")) {
|
if (@hasDecl(apprt.Surface, "newTab")) {
|
||||||
try self.rt_surface.newTab();
|
try self.rt_surface.newTab();
|
||||||
|
@ -86,7 +86,8 @@ pub const App = struct {
|
|||||||
/// New tab with options.
|
/// New tab with options.
|
||||||
new_tab: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null,
|
new_tab: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null,
|
||||||
|
|
||||||
/// New window with options.
|
/// New window with options. The surface may be null if there is no
|
||||||
|
/// target surface.
|
||||||
new_window: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null,
|
new_window: ?*const fn (SurfaceUD, apprt.Surface.Options) callconv(.C) void = null,
|
||||||
|
|
||||||
/// Control the inspector visibility
|
/// Control the inspector visibility
|
||||||
@ -495,14 +496,19 @@ pub const App = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn newWindow(self: *App, parent: ?*CoreSurface) !void {
|
pub fn newWindow(self: *App, parent: ?*CoreSurface) !void {
|
||||||
_ = self;
|
// If we have a parent, the surface logic handles it.
|
||||||
|
|
||||||
// Right now we only support creating a new window with a parent
|
|
||||||
// through this code.
|
|
||||||
// The other case is handled by the embedding runtime.
|
|
||||||
if (parent) |surface| {
|
if (parent) |surface| {
|
||||||
try surface.rt_surface.newWindow();
|
try surface.rt_surface.newWindow();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No parent, call the new window callback.
|
||||||
|
const func = self.opts.new_window orelse {
|
||||||
|
log.info("runtime embedder does not support new_window", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
func(null, .{});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -279,7 +279,8 @@ pub const Action = union(enum) {
|
|||||||
/// available values.
|
/// available values.
|
||||||
write_selection_file: WriteScreenAction,
|
write_selection_file: WriteScreenAction,
|
||||||
|
|
||||||
/// Open a new window.
|
/// Open a new window. If the application isn't currently focused,
|
||||||
|
/// this will bring it to the front.
|
||||||
new_window: void,
|
new_window: void,
|
||||||
|
|
||||||
/// Open a new tab.
|
/// Open a new tab.
|
||||||
@ -562,6 +563,10 @@ pub const Action = union(enum) {
|
|||||||
.quit,
|
.quit,
|
||||||
=> .app,
|
=> .app,
|
||||||
|
|
||||||
|
// These are app but can be special-cased in a surface context.
|
||||||
|
.new_window,
|
||||||
|
=> .app,
|
||||||
|
|
||||||
// Obviously surface actions.
|
// Obviously surface actions.
|
||||||
.csi,
|
.csi,
|
||||||
.esc,
|
.esc,
|
||||||
@ -593,12 +598,12 @@ pub const Action = union(enum) {
|
|||||||
.toggle_window_decorations,
|
.toggle_window_decorations,
|
||||||
.toggle_secure_input,
|
.toggle_secure_input,
|
||||||
.crash,
|
.crash,
|
||||||
|
=> .surface,
|
||||||
|
|
||||||
// These are less obvious surface actions. They're surface
|
// These are less obvious surface actions. They're surface
|
||||||
// actions because they are relevant to the surface they
|
// actions because they are relevant to the surface they
|
||||||
// come from. For example `new_window` needs to be sourced to
|
// come from. For example `new_window` needs to be sourced to
|
||||||
// a surface so inheritance can be done correctly.
|
// a surface so inheritance can be done correctly.
|
||||||
.new_window,
|
|
||||||
.new_tab,
|
.new_tab,
|
||||||
.previous_tab,
|
.previous_tab,
|
||||||
.next_tab,
|
.next_tab,
|
||||||
|
Reference in New Issue
Block a user