mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-20 18:56:08 +03:00
apprt/gtk-ng: introduce a basic surface
This commit is contained in:
@ -31,6 +31,7 @@ pub const icon_sizes: []const comptime_int = &.{ 16, 32, 128, 256, 512, 1024 };
|
|||||||
/// These will be asserted to exist at runtime.
|
/// These will be asserted to exist at runtime.
|
||||||
pub const blueprints: []const Blueprint = &.{
|
pub const blueprints: []const Blueprint = &.{
|
||||||
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
|
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
|
||||||
|
.{ .major = 1, .minor = 2, .name = "surface" },
|
||||||
.{ .major = 1, .minor = 5, .name = "config-errors-dialog" },
|
.{ .major = 1, .minor = 5, .name = "config-errors-dialog" },
|
||||||
.{ .major = 1, .minor = 5, .name = "window" },
|
.{ .major = 1, .minor = 5, .name = "window" },
|
||||||
};
|
};
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
const glib = @import("glib");
|
const glib = @import("glib");
|
||||||
const gobject = @import("gobject");
|
const gobject = @import("gobject");
|
||||||
|
const gtk = @import("gtk");
|
||||||
|
|
||||||
pub const Application = @import("class/application.zig").Application;
|
pub const Application = @import("class/application.zig").Application;
|
||||||
pub const Window = @import("class/window.zig").Window;
|
pub const Window = @import("class/window.zig").Window;
|
||||||
pub const Config = @import("class/config.zig").Config;
|
pub const Config = @import("class/config.zig").Config;
|
||||||
|
pub const Surface = @import("class/surface.zig").Surface;
|
||||||
|
|
||||||
/// Unrefs the given GObject on the next event loop tick.
|
/// Unrefs the given GObject on the next event loop tick.
|
||||||
///
|
///
|
||||||
@ -60,6 +62,30 @@ pub fn Common(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}).private else {};
|
}).private else {};
|
||||||
|
|
||||||
|
/// Common class functions.
|
||||||
|
pub const Class = struct {
|
||||||
|
pub fn as(class: *Self.Class, comptime T: type) *T {
|
||||||
|
return gobject.ext.as(T, class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bind a template child to a private entry in the class.
|
||||||
|
pub const bindTemplateChildPrivate = if (Private) |P| (struct {
|
||||||
|
pub fn bindTemplateChildPrivate(
|
||||||
|
class: *Self.Class,
|
||||||
|
comptime name: [:0]const u8,
|
||||||
|
comptime options: gtk.ext.BindTemplateChildOptions,
|
||||||
|
) void {
|
||||||
|
gtk.ext.impl_helpers.bindTemplateChildPrivate(
|
||||||
|
class,
|
||||||
|
name,
|
||||||
|
P,
|
||||||
|
P.offset,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).bindTemplateChildPrivate else {};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ const configpkg = @import("../../../config.zig");
|
|||||||
const internal_os = @import("../../../os/main.zig");
|
const internal_os = @import("../../../os/main.zig");
|
||||||
const xev = @import("../../../global.zig").xev;
|
const xev = @import("../../../global.zig").xev;
|
||||||
const CoreConfig = configpkg.Config;
|
const CoreConfig = configpkg.Config;
|
||||||
|
const CoreSurface = @import("../../../Surface.zig");
|
||||||
|
|
||||||
const adw_version = @import("../adw_version.zig");
|
const adw_version = @import("../adw_version.zig");
|
||||||
const gtk_version = @import("../gtk_version.zig");
|
const gtk_version = @import("../gtk_version.zig");
|
||||||
@ -58,6 +59,25 @@ pub const Application = extern struct {
|
|||||||
.private = .{ .Type = Private, .offset = &Private.offset },
|
.private = .{ .Type = Private, .offset = &Private.offset },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pub const properties = struct {
|
||||||
|
pub const config = struct {
|
||||||
|
pub const name = "config";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
"config",
|
||||||
|
Self,
|
||||||
|
?*Config,
|
||||||
|
.{
|
||||||
|
.nick = "Config",
|
||||||
|
.blurb = "The current active configuration for the application.",
|
||||||
|
.default = null,
|
||||||
|
.accessor = .{
|
||||||
|
.getter = Self.getPropConfig,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const Private = struct {
|
const Private = struct {
|
||||||
/// The apprt App. This is annoying that we need this it'd be
|
/// The apprt App. This is annoying that we need this it'd be
|
||||||
/// nicer to just make THIS the apprt app but the current libghostty
|
/// nicer to just make THIS the apprt app but the current libghostty
|
||||||
@ -88,6 +108,17 @@ pub const Application = extern struct {
|
|||||||
pub var offset: c_int = 0;
|
pub var offset: c_int = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Get this application as the default, allowing access to its
|
||||||
|
/// properties globally.
|
||||||
|
///
|
||||||
|
/// This asserts that there is a default application and that the
|
||||||
|
/// default application is a GhosttyApplication. The program would have
|
||||||
|
/// to be in a very bad state for this to be violated.
|
||||||
|
pub fn default() *Self {
|
||||||
|
const app = gio.Application.getDefault().?;
|
||||||
|
return gobject.ext.cast(Self, app).?;
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new Application instance.
|
/// Creates a new Application instance.
|
||||||
///
|
///
|
||||||
/// This does a lot more work than a typical class instantiation,
|
/// This does a lot more work than a typical class instantiation,
|
||||||
@ -121,14 +152,14 @@ pub const Application = extern struct {
|
|||||||
// the error in the diagnostics so it can be shown to the user.
|
// the error in the diagnostics so it can be shown to the user.
|
||||||
// We can still load a default which only fails for OOM, allowing
|
// We can still load a default which only fails for OOM, allowing
|
||||||
// us to startup.
|
// us to startup.
|
||||||
var default: CoreConfig = try .default(alloc);
|
var def: CoreConfig = try .default(alloc);
|
||||||
errdefer default.deinit();
|
errdefer def.deinit();
|
||||||
try default.addDiagnosticFmt(
|
try def.addDiagnosticFmt(
|
||||||
"error loading user configuration: {}",
|
"error loading user configuration: {}",
|
||||||
.{err},
|
.{err},
|
||||||
);
|
);
|
||||||
|
|
||||||
break :err default;
|
break :err def;
|
||||||
};
|
};
|
||||||
defer config.deinit();
|
defer config.deinit();
|
||||||
|
|
||||||
@ -223,6 +254,13 @@ pub const Application = extern struct {
|
|||||||
if (priv.transient_cgroup_base) |base| alloc.free(base);
|
if (priv.transient_cgroup_base) |base| alloc.free(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The global allocator that all other classes should use by
|
||||||
|
/// calling `Application.default().allocator()`. Zig code should prefer
|
||||||
|
/// this wherever possible so we get leak detection in debug/tests.
|
||||||
|
pub fn allocator(self: *Self) std.mem.Allocator {
|
||||||
|
return self.private().core_app.alloc;
|
||||||
|
}
|
||||||
|
|
||||||
/// Run the application. This is a replacement for `gio.Application.run`
|
/// Run the application. This is a replacement for `gio.Application.run`
|
||||||
/// because we want more tight control over our event loop so we can
|
/// because we want more tight control over our event loop so we can
|
||||||
/// integrate it with libghostty.
|
/// integrate it with libghostty.
|
||||||
@ -332,9 +370,16 @@ pub const Application = extern struct {
|
|||||||
value.config,
|
value.config,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
.new_window => try Action.newWindow(
|
||||||
|
self,
|
||||||
|
switch (target) {
|
||||||
|
.app => null,
|
||||||
|
.surface => |v| v,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
// Unimplemented
|
// Unimplemented
|
||||||
.quit,
|
.quit,
|
||||||
.new_window,
|
|
||||||
.close_window,
|
.close_window,
|
||||||
.toggle_maximize,
|
.toggle_maximize,
|
||||||
.toggle_fullscreen,
|
.toggle_fullscreen,
|
||||||
@ -410,6 +455,27 @@ pub const Application = extern struct {
|
|||||||
try priv.core_app.updateConfig(priv.rt_app, &config);
|
try priv.core_app.updateConfig(priv.rt_app, &config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the configuration for this application.
|
||||||
|
///
|
||||||
|
/// The reference count is increased.
|
||||||
|
pub fn getConfig(self: *Self) *Config {
|
||||||
|
var value = gobject.ext.Value.zero;
|
||||||
|
gobject.Object.getProperty(
|
||||||
|
self.as(gobject.Object),
|
||||||
|
properties.config.name,
|
||||||
|
&value,
|
||||||
|
);
|
||||||
|
|
||||||
|
const obj = value.getObject().?;
|
||||||
|
return gobject.ext.cast(Config, obj).?;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getPropConfig(self: *Self) *Config {
|
||||||
|
// Property return must not increase reference count since
|
||||||
|
// the gobject getter handles this automatically.
|
||||||
|
return self.private().config;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
||||||
// Virtual Methods
|
// Virtual Methods
|
||||||
|
|
||||||
@ -421,6 +487,9 @@ pub const Application = extern struct {
|
|||||||
self.as(Parent),
|
self.as(Parent),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set ourselves as the default application.
|
||||||
|
gio.Application.setDefault(self.as(gio.Application));
|
||||||
|
|
||||||
// Setup our event loop
|
// Setup our event loop
|
||||||
self.startupXev();
|
self.startupXev();
|
||||||
|
|
||||||
@ -581,14 +650,17 @@ pub const Application = extern struct {
|
|||||||
fn activate(self: *Self) callconv(.C) void {
|
fn activate(self: *Self) callconv(.C) void {
|
||||||
log.debug("activate", .{});
|
log.debug("activate", .{});
|
||||||
|
|
||||||
|
// Queue a new window
|
||||||
|
const priv = self.private();
|
||||||
|
_ = priv.core_app.mailbox.push(.{
|
||||||
|
.new_window = .{},
|
||||||
|
}, .{ .forever = {} });
|
||||||
|
|
||||||
// Call the parent activate method.
|
// Call the parent activate method.
|
||||||
gio.Application.virtual_methods.activate.call(
|
gio.Application.virtual_methods.activate.call(
|
||||||
Class.parent,
|
Class.parent,
|
||||||
self.as(Parent),
|
self.as(Parent),
|
||||||
);
|
);
|
||||||
|
|
||||||
// const win = Window.new(self);
|
|
||||||
// gtk.Window.present(win.as(gtk.Window));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispose(self: *Self) callconv(.C) void {
|
fn dispose(self: *Self) callconv(.C) void {
|
||||||
@ -697,10 +769,6 @@ pub const Application = extern struct {
|
|||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
// Boilerplate/Noise
|
// Boilerplate/Noise
|
||||||
|
|
||||||
fn allocator(self: *Self) std.mem.Allocator {
|
|
||||||
return self.private().core_app.alloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
const C = Common(Self, Private);
|
const C = Common(Self, Private);
|
||||||
pub const as = C.as;
|
pub const as = C.as;
|
||||||
pub const ref = C.ref;
|
pub const ref = C.ref;
|
||||||
@ -729,6 +797,11 @@ pub const Application = extern struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
gobject.ext.registerProperties(class, &.{
|
||||||
|
properties.config.impl,
|
||||||
|
});
|
||||||
|
|
||||||
// Virtual methods
|
// Virtual methods
|
||||||
gio.Application.virtual_methods.activate.implement(class, &activate);
|
gio.Application.virtual_methods.activate.implement(class, &activate);
|
||||||
gio.Application.virtual_methods.startup.implement(class, &startup);
|
gio.Application.virtual_methods.startup.implement(class, &startup);
|
||||||
@ -765,6 +838,16 @@ const Action = struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn newWindow(
|
||||||
|
self: *Application,
|
||||||
|
parent: ?*CoreSurface,
|
||||||
|
) !void {
|
||||||
|
_ = parent;
|
||||||
|
|
||||||
|
const win = Window.new(self);
|
||||||
|
gtk.Window.present(win.as(gtk.Window));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This sets various GTK-related environment variables as necessary
|
/// This sets various GTK-related environment variables as necessary
|
||||||
|
166
src/apprt/gtk-ng/class/surface.zig
Normal file
166
src/apprt/gtk-ng/class/surface.zig
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const adw = @import("adw");
|
||||||
|
const gobject = @import("gobject");
|
||||||
|
const gtk = @import("gtk");
|
||||||
|
|
||||||
|
const renderer = @import("../../../renderer.zig");
|
||||||
|
const gresource = @import("../build/gresource.zig");
|
||||||
|
const adw_version = @import("../adw_version.zig");
|
||||||
|
const Common = @import("../class.zig").Common;
|
||||||
|
const Application = @import("application.zig").Application;
|
||||||
|
const Config = @import("config.zig").Config;
|
||||||
|
|
||||||
|
const log = std.log.scoped(.gtk_ghostty_surface);
|
||||||
|
|
||||||
|
pub const Surface = extern struct {
|
||||||
|
const Self = @This();
|
||||||
|
parent_instance: Parent,
|
||||||
|
pub const Parent = adw.Bin;
|
||||||
|
pub const getGObjectType = gobject.ext.defineClass(Self, .{
|
||||||
|
.name = "GhosttySurface",
|
||||||
|
.instanceInit = &init,
|
||||||
|
.classInit = &Class.init,
|
||||||
|
.parent_class = &Class.parent,
|
||||||
|
.private = .{ .Type = Private, .offset = &Private.offset },
|
||||||
|
});
|
||||||
|
|
||||||
|
pub const properties = struct {
|
||||||
|
pub const config = struct {
|
||||||
|
pub const name = "config";
|
||||||
|
const impl = gobject.ext.defineProperty(
|
||||||
|
name,
|
||||||
|
Self,
|
||||||
|
?*Config,
|
||||||
|
.{
|
||||||
|
.nick = "Config",
|
||||||
|
.blurb = "The configuration that this surface is using.",
|
||||||
|
.default = null,
|
||||||
|
.accessor = gobject.ext.privateFieldAccessor(
|
||||||
|
Self,
|
||||||
|
Private,
|
||||||
|
&Private.offset,
|
||||||
|
"config",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Private = struct {
|
||||||
|
/// The configuration that this surface is using.
|
||||||
|
config: ?*Config = null,
|
||||||
|
|
||||||
|
/// The GLAarea that renders the actual surface. This is a binding
|
||||||
|
/// to the template so it doesn't have to be unrefed manually.
|
||||||
|
gl_area: *gtk.GLArea,
|
||||||
|
|
||||||
|
pub var offset: c_int = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn new() *Self {
|
||||||
|
return gobject.ext.newInstance(Self, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(self: *Self, _: *Class) callconv(.C) void {
|
||||||
|
gtk.Widget.initTemplate(self.as(gtk.Widget));
|
||||||
|
|
||||||
|
const priv = self.private();
|
||||||
|
|
||||||
|
// If our configuration is null then we get the configuration
|
||||||
|
// from the application.
|
||||||
|
if (priv.config == null) {
|
||||||
|
const app = Application.default();
|
||||||
|
priv.config = app.getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize our GLArea. We could do a lot of this in
|
||||||
|
// the Blueprint file but I think its cleaner to separate
|
||||||
|
// the "UI" part of the blueprint file from the internal logic/config
|
||||||
|
// part.
|
||||||
|
const gl_area = priv.gl_area;
|
||||||
|
gl_area.setRequiredVersion(
|
||||||
|
renderer.OpenGL.MIN_VERSION_MAJOR,
|
||||||
|
renderer.OpenGL.MIN_VERSION_MINOR,
|
||||||
|
);
|
||||||
|
gl_area.setHasStencilBuffer(0);
|
||||||
|
gl_area.setHasDepthBuffer(0);
|
||||||
|
gl_area.setUseEs(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispose(self: *Self) callconv(.C) void {
|
||||||
|
const priv = self.private();
|
||||||
|
if (priv.config) |v| {
|
||||||
|
v.unref();
|
||||||
|
priv.config = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk.Widget.disposeTemplate(
|
||||||
|
self.as(gtk.Widget),
|
||||||
|
getGObjectType(),
|
||||||
|
);
|
||||||
|
|
||||||
|
gobject.Object.virtual_methods.dispose.call(
|
||||||
|
Class.parent,
|
||||||
|
self.as(Parent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn realize(self: *Self) callconv(.C) void {
|
||||||
|
log.debug("realize", .{});
|
||||||
|
|
||||||
|
// Call the parent class's realize method.
|
||||||
|
gtk.Widget.virtual_methods.realize.call(
|
||||||
|
Class.parent,
|
||||||
|
self.as(Parent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unrealize(self: *Self) callconv(.C) void {
|
||||||
|
log.debug("unrealize", .{});
|
||||||
|
|
||||||
|
// Call the parent class's unrealize method.
|
||||||
|
gtk.Widget.virtual_methods.unrealize.call(
|
||||||
|
Class.parent,
|
||||||
|
self.as(Parent),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const C = Common(Self, Private);
|
||||||
|
pub const as = C.as;
|
||||||
|
pub const ref = C.ref;
|
||||||
|
pub const unref = C.unref;
|
||||||
|
const private = C.private;
|
||||||
|
|
||||||
|
pub const Class = extern struct {
|
||||||
|
parent_class: Parent.Class,
|
||||||
|
var parent: *Parent.Class = undefined;
|
||||||
|
pub const Instance = Self;
|
||||||
|
|
||||||
|
fn init(class: *Class) callconv(.C) void {
|
||||||
|
gtk.Widget.Class.setTemplateFromResource(
|
||||||
|
class.as(gtk.Widget.Class),
|
||||||
|
comptime gresource.blueprint(.{
|
||||||
|
.major = 1,
|
||||||
|
.minor = 2,
|
||||||
|
.name = "surface",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Bindings
|
||||||
|
class.bindTemplateChildPrivate("gl_area", .{});
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
gobject.ext.registerProperties(class, &.{
|
||||||
|
properties.config.impl,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Virtual methods
|
||||||
|
gobject.Object.virtual_methods.dispose.implement(class, &dispose);
|
||||||
|
gtk.Widget.virtual_methods.realize.implement(class, &realize);
|
||||||
|
gtk.Widget.virtual_methods.unrealize.implement(class, &unrealize);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const as = C.Class.as;
|
||||||
|
pub const bindTemplateChildPrivate = C.Class.bindTemplateChildPrivate;
|
||||||
|
};
|
||||||
|
};
|
@ -6,6 +6,7 @@ const gtk = @import("gtk");
|
|||||||
const gresource = @import("../build/gresource.zig");
|
const gresource = @import("../build/gresource.zig");
|
||||||
const Common = @import("../class.zig").Common;
|
const Common = @import("../class.zig").Common;
|
||||||
const Application = @import("application.zig").Application;
|
const Application = @import("application.zig").Application;
|
||||||
|
const Surface = @import("surface.zig").Surface;
|
||||||
|
|
||||||
const log = std.log.scoped(.gtk_ghostty_window);
|
const log = std.log.scoped(.gtk_ghostty_window);
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ pub const Window = extern struct {
|
|||||||
pub const Instance = Self;
|
pub const Instance = Self;
|
||||||
|
|
||||||
fn init(class: *Class) callconv(.C) void {
|
fn init(class: *Class) callconv(.C) void {
|
||||||
|
gobject.ext.ensureType(Surface);
|
||||||
|
|
||||||
gtk.Widget.Class.setTemplateFromResource(
|
gtk.Widget.Class.setTemplateFromResource(
|
||||||
class.as(gtk.Widget.Class),
|
class.as(gtk.Widget.Class),
|
||||||
comptime gresource.blueprint(.{
|
comptime gresource.blueprint(.{
|
||||||
|
18
src/apprt/gtk-ng/ui/1.2/surface.blp
Normal file
18
src/apprt/gtk-ng/ui/1.2/surface.blp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
template $GhosttySurface: Adw.Bin {
|
||||||
|
Box {
|
||||||
|
orientation: vertical;
|
||||||
|
hexpand: true;
|
||||||
|
|
||||||
|
Label {
|
||||||
|
label: "Hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
GLArea gl_area {
|
||||||
|
hexpand: true;
|
||||||
|
vexpand: true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,5 @@ using Gtk 4.0;
|
|||||||
using Adw 1;
|
using Adw 1;
|
||||||
|
|
||||||
template $GhosttyWindow: Adw.ApplicationWindow {
|
template $GhosttyWindow: Adw.ApplicationWindow {
|
||||||
content: Label {
|
content: $GhosttySurface {};
|
||||||
label: "Hello, Ghostty!";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,39 @@
|
|||||||
# You must gracefully exit Ghostty (do not SIGINT) by closing all windows
|
# You must gracefully exit Ghostty (do not SIGINT) by closing all windows
|
||||||
# and quitting. Otherwise, we leave a number of GTK resources around.
|
# and quitting. Otherwise, we leave a number of GTK resources around.
|
||||||
|
|
||||||
|
{
|
||||||
|
GSK Renderer GPU Stuff
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: possible
|
||||||
|
...
|
||||||
|
fun:gsk_gpu_image_toggle_ref_texture
|
||||||
|
fun:gsk_gl_image_new_for_texture
|
||||||
|
fun:gsk_gl_frame_upload_texture
|
||||||
|
fun:gsk_gpu_frame_do_upload_texture
|
||||||
|
fun:gsk_gpu_lookup_texture
|
||||||
|
...
|
||||||
|
fun:gsk_gpu_node_processor_add_first_node
|
||||||
|
fun:gsk_gpu_node_processor_process
|
||||||
|
fun:gsk_gpu_frame_render
|
||||||
|
fun:gsk_gpu_renderer_render
|
||||||
|
fun:gsk_renderer_render
|
||||||
|
fun:gtk_widget_render
|
||||||
|
fun:surface_render
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
GTK Shader Selector
|
||||||
|
Memcheck:Leak
|
||||||
|
match-leak-kinds: possible
|
||||||
|
...
|
||||||
|
fun:_ZL29si_init_shader_selector_asyncPvS_i
|
||||||
|
fun:util_queue_thread_func
|
||||||
|
fun:impl_thrd_routine
|
||||||
|
fun:start_thread
|
||||||
|
fun:clone
|
||||||
|
}
|
||||||
|
|
||||||
# Weird gtk_tooltip_init leak I can't figure out
|
# Weird gtk_tooltip_init leak I can't figure out
|
||||||
{
|
{
|
||||||
Non-builder tooltip create
|
Non-builder tooltip create
|
||||||
|
Reference in New Issue
Block a user