Enhancement: Fixes #340, Shell icon view behaviour support for the desktop

This commit is contained in:
Rory Fewell
2025-10-25 18:40:05 +01:00
parent f53b11b7ef
commit a2c780b873
23 changed files with 790 additions and 160 deletions

View File

@@ -46,6 +46,8 @@ add_library(
public/dialog.h
src/error.c
public/error.h
src/fldropts.c
public/fldropts.h
src/fsclipbd.c
public/fsclipbd.h
src/fsop.c

View File

@@ -7,6 +7,8 @@
#include <gtk/gtk.h>
#include <wintc/shellext.h>
#include "fldropts.h"
//
// PUBLIC ENUMS
//
@@ -16,6 +18,11 @@ typedef enum
WINTC_SH_BROWSER_LOAD_FINISHED
} WinTCShBrowserLoadEvent;
typedef enum
{
WINTC_SH_BROWSER_BEHAVIOUR_DONT_USE_SELF_EXE = 0x1
} WinTCShBrowserBehaviourFlag;
//
// GTK OOP BOILERPLATE
//
@@ -39,7 +46,8 @@ GType wintc_sh_browser_get_type(void) G_GNUC_CONST;
// PUBLIC FUNCTIONS
//
WinTCShBrowser* wintc_sh_browser_new(
WinTCShextHost* shext_host
WinTCShextHost* shext_host,
WinTCShFolderOptions* fldr_opts
);
gboolean wintc_sh_browser_activate_item(
@@ -56,6 +64,10 @@ WinTCIShextView* wintc_sh_browser_get_current_view(
WinTCShBrowser* browser
);
WinTCShBrowserBehaviourFlag wintc_sh_browser_get_behaviour_flags(
WinTCShBrowser* browser
);
void wintc_sh_browser_get_location(
WinTCShBrowser* browser,
WinTCShextPathInfo* path_info
@@ -77,6 +89,11 @@ void wintc_sh_browser_refresh(
WinTCShBrowser* browser
);
void wintc_sh_browser_set_behaviour_flags(
WinTCShBrowser* browser,
WinTCShBrowserBehaviourFlag flags
);
gboolean wintc_sh_browser_set_location(
WinTCShBrowser* browser,
const WinTCShextPathInfo* path_info,

View File

@@ -0,0 +1,32 @@
#ifndef __SHELL_FLDROPTS_H__
#define __SHELL_FLDROPTS_H__
#include <glib.h>
//
// GTK OOP BOILERPLATE
//
#define WINTC_TYPE_SH_FOLDER_OPTIONS (wintc_sh_folder_options_get_type())
G_DECLARE_FINAL_TYPE(
WinTCShFolderOptions,
wintc_sh_folder_options,
WINTC,
SH_FOLDER_OPTIONS,
GObject
)
//
// PUBLIC FUNCTIONS
//
WinTCShFolderOptions* wintc_sh_folder_options_new(void);
gboolean wintc_sh_folder_options_get_browse_in_same_window(
WinTCShFolderOptions* fldr_opts
);
void wintc_sh_folder_options_set_browse_in_same_window(
WinTCShFolderOptions* fldr_opts,
gboolean browse_in_same_window
);
#endif

View File

@@ -5,7 +5,9 @@
#include "@LIB_HEADER_DIR@/cpl.h"
#include "@LIB_HEADER_DIR@/dialog.h"
#include "@LIB_HEADER_DIR@/error.h"
#include "@LIB_HEADER_DIR@/fldropts.h"
#include "@LIB_HEADER_DIR@/fsclipbd.h"
#include "@LIB_HEADER_DIR@/fsop.h"
#include "@LIB_HEADER_DIR@/icnvwbeh.h"
#include "@LIB_HEADER_DIR@/nmspace.h"
#include "@LIB_HEADER_DIR@/sound.h"

View File

@@ -2,16 +2,21 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/exec.h>
#include <wintc/shellext.h>
#include "../public/browser.h"
#include "../public/fldropts.h"
//
// PRIVATE ENUMS
//
enum
{
PROP_SHEXT_HOST = 1
PROP_NULL,
PROP_SHEXT_HOST,
PROP_FOLDER_OPTIONS,
N_PROPERTIES
};
enum
@@ -23,11 +28,15 @@ enum
//
// STATIC DATA
//
static gint wintc_sh_browser_signals[N_SIGNALS] = { 0 };
static GParamSpec* wintc_sh_browser_properties[N_PROPERTIES] = { 0 };
static gint wintc_sh_browser_signals[N_SIGNALS] = { 0 };
//
// FORWARD DECLARATIONS
//
static void wintc_sh_browser_constructed(
GObject* object
);
static void wintc_sh_browser_dispose(
GObject* object
);
@@ -62,7 +71,12 @@ struct _WinTCShBrowser
{
GObject __parent__;
WinTCShextHost* shext_host;
WinTCShBrowserBehaviourFlag flags;
// Shell state
//
WinTCShFolderOptions* fldr_opts;
WinTCShextHost* shext_host;
// Browser state
//
@@ -86,20 +100,32 @@ static void wintc_sh_browser_class_init(
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->constructed = wintc_sh_browser_constructed;
object_class->dispose = wintc_sh_browser_dispose;
object_class->get_property = wintc_sh_browser_get_property;
object_class->set_property = wintc_sh_browser_set_property;
g_object_class_install_property(
object_class,
PROP_SHEXT_HOST,
wintc_sh_browser_properties[PROP_SHEXT_HOST] =
g_param_spec_object(
"shext-host",
"ShextHost",
"The shell extension host object to use.",
WINTC_TYPE_SHEXT_HOST,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
wintc_sh_browser_properties[PROP_FOLDER_OPTIONS] =
g_param_spec_object(
"folder-options",
"FolderOptions",
"The folder options object to use.",
WINTC_TYPE_SH_FOLDER_OPTIONS,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
);
g_object_class_install_properties(
object_class,
N_PROPERTIES,
wintc_sh_browser_properties
);
wintc_sh_browser_signals[SIGNAL_LOAD_CHANGED] =
@@ -124,12 +150,28 @@ static void wintc_sh_browser_init(
//
// CLASS VIRTUAL METHODS
//
static void wintc_sh_browser_constructed(
GObject* object
)
{
(G_OBJECT_CLASS(wintc_sh_browser_parent_class))
->constructed(object);
WinTCShBrowser* browser = WINTC_SH_BROWSER(object);
if (!(browser->fldr_opts))
{
browser->fldr_opts = wintc_sh_folder_options_new();
}
}
static void wintc_sh_browser_dispose(
GObject* object
)
{
WinTCShBrowser* browser = WINTC_SH_BROWSER(object);
g_clear_object(&(browser->fldr_opts));
g_clear_object(&(browser->shext_host));
g_clear_object(&(browser->current_view));
@@ -163,6 +205,10 @@ static void wintc_sh_browser_set_property(
switch (prop_id)
{
case PROP_FOLDER_OPTIONS:
browser->fldr_opts = g_value_dup_object(value);
break;
case PROP_SHEXT_HOST:
browser->shext_host = g_value_dup_object(value);
break;
@@ -177,13 +223,15 @@ static void wintc_sh_browser_set_property(
// PUBLIC FUNCTIONS
//
WinTCShBrowser* wintc_sh_browser_new(
WinTCShextHost* shext_host
WinTCShextHost* shext_host,
WinTCShFolderOptions* fldr_opts
)
{
return WINTC_SH_BROWSER(
g_object_new(
WINTC_TYPE_SH_BROWSER,
"shext-host", shext_host,
"shext-host", shext_host,
"folder-options", fldr_opts,
NULL
)
);
@@ -231,12 +279,51 @@ gboolean wintc_sh_browser_activate_item(
// Navigate to the path
//
gboolean success =
wintc_sh_browser_set_location(
browser,
&path_info,
&local_error
);
gboolean success;
if (wintc_sh_folder_options_get_browse_in_same_window(browser->fldr_opts))
{
success =
wintc_sh_browser_set_location(
browser,
&path_info,
&local_error
);
}
else
{
gchar* path = wintc_shext_path_info_get_as_single_path(&path_info);
// Determine what to open with, us or explorer
//
GApplication* app = g_application_get_default();
if (
browser->flags & WINTC_SH_BROWSER_BEHAVIOUR_DONT_USE_SELF_EXE ||
!app
)
{
gchar* cmdline = g_strdup_printf("explorer \"%s\"", path);
success =
wintc_launch_command(
cmdline,
&local_error
);
g_free(cmdline);
}
else
{
GFile* file = g_file_new_for_path(path);
g_application_open(app, &file, 1, NULL);
success = TRUE;
}
g_free(path);
}
if (!success)
{
@@ -261,6 +348,13 @@ gboolean wintc_sh_browser_can_navigate_to_parent(
return wintc_ishext_view_has_parent(browser->current_view);
}
WinTCShBrowserBehaviourFlag wintc_sh_browser_get_behaviour_flags(
WinTCShBrowser* browser
)
{
return browser->flags;
}
WinTCIShextView* wintc_sh_browser_get_current_view(
WinTCShBrowser* browser
)
@@ -333,6 +427,14 @@ void wintc_sh_browser_refresh(
wintc_ishext_view_refresh_items(browser->current_view);
}
void wintc_sh_browser_set_behaviour_flags(
WinTCShBrowser* browser,
WinTCShBrowserBehaviourFlag flags
)
{
browser->flags = flags;
}
gboolean wintc_sh_browser_set_location(
WinTCShBrowser* browser,
const WinTCShextPathInfo* path_info,

155
shared/shell/src/fldropts.c Normal file
View File

@@ -0,0 +1,155 @@
#include <glib.h>
#include <wintc/comgtk.h>
#include "../public/fldropts.h"
//
// PRIVATE ENUMS
//
enum
{
PROP_NULL,
PROP_BROWSE_IN_SAME_WINDOW,
N_PROPERTIES
};
//
// FORWARD DECLARATIONS
//
static void wintc_sh_folder_options_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
);
static void wintc_sh_folder_options_set_property(
GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec
);
//
// STATIC DATA
//
static GParamSpec* wintc_sh_folder_options_properties[N_PROPERTIES] = { 0 };
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCShFolderOptions
{
GObject __parent__;
// Settings
//
gboolean browse_in_same_window;
};
//
// GTK TYPE DEFINITIONS & CTORS
//
G_DEFINE_TYPE(
WinTCShFolderOptions,
wintc_sh_folder_options,
G_TYPE_OBJECT
)
static void wintc_sh_folder_options_class_init(
WinTCShFolderOptionsClass* klass
)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->get_property = wintc_sh_folder_options_get_property;
object_class->set_property = wintc_sh_folder_options_set_property;
wintc_sh_folder_options_properties[PROP_BROWSE_IN_SAME_WINDOW] =
g_param_spec_boolean(
"browse-in-same-window",
"BrowseInSameWindow",
"Determines whether to open folders in the same window.",
TRUE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT
);
g_object_class_install_properties(
object_class,
N_PROPERTIES,
wintc_sh_folder_options_properties
);
}
static void wintc_sh_folder_options_init(
WINTC_UNUSED(WinTCShFolderOptions* self)
) {}
//
// CLASS VIRTUAL METHODS
//
static void wintc_sh_folder_options_get_property(
GObject* object,
guint prop_id,
GValue* value,
GParamSpec* pspec
)
{
WinTCShFolderOptions* fldr_opts = WINTC_SH_FOLDER_OPTIONS(object);
switch (prop_id)
{
case PROP_BROWSE_IN_SAME_WINDOW:
g_value_set_boolean(value, fldr_opts->browse_in_same_window);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void wintc_sh_folder_options_set_property(
GObject* object,
guint prop_id,
const GValue* value,
GParamSpec* pspec
)
{
WinTCShFolderOptions* fldr_opts = WINTC_SH_FOLDER_OPTIONS(object);
switch (prop_id)
{
case PROP_BROWSE_IN_SAME_WINDOW:
fldr_opts->browse_in_same_window = g_value_get_boolean(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
//
// PUBLIC FUNCTIONS
//
WinTCShFolderOptions* wintc_sh_folder_options_new(void)
{
return WINTC_SH_FOLDER_OPTIONS(
g_object_new(WINTC_TYPE_SH_FOLDER_OPTIONS, NULL)
);
}
gboolean wintc_sh_folder_options_get_browse_in_same_window(
WinTCShFolderOptions* fldr_opts
)
{
return fldr_opts->browse_in_same_window;
}
void wintc_sh_folder_options_set_browse_in_same_window(
WinTCShFolderOptions* fldr_opts,
gboolean browse_in_same_window
)
{
fldr_opts->browse_in_same_window = browse_in_same_window;
}

View File

@@ -7,25 +7,19 @@
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCDpaDesktopWindowClass
#define WINTC_TYPE_DPA_DESKTOP_WINDOW (wintc_dpa_desktop_window_get_type())
G_DECLARE_DERIVABLE_TYPE(
WinTCDpaDesktopWindow,
wintc_dpa_desktop_window,
WINTC,
DPA_DESKTOP_WINDOW,
GtkApplicationWindow
)
struct _WinTCDpaDesktopWindowClass
{
GtkApplicationWindowClass __parent__;
} WinTCDpaDesktopWindowClass;
typedef struct _WinTCDpaDesktopWindow
{
GtkApplicationWindow __parent__;
GdkMonitor* monitor;
} WinTCDpaDesktopWindow;
#define WINTC_TYPE_DPA_DESKTOP_WINDOW (wintc_dpa_desktop_window_get_type())
#define WINTC_DPA_DESKTOP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_DPA_DESKTOP_WINDOW, WinTCDpaDesktopWindow))
#define WINTC_DPA_DESKTOP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_DPA_DESKTOP_WINDOW, WinTCDpaDesktopWindow))
#define IS_WINTC_DPA_DESKTOP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_DPA_DESKTOP_WINDOW))
#define IS_WINTC_DPA_DESKTOP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_DPA_DESKTOP_WINDOW))
#define WINTC_DPA_DESKTOP_WINDOW_GET_CLASS(obj) (G_TYPE_CHECK_INSTANCE_GET_CLASS((obj), WINTC_TYPE_DPA_DESKTOP_WINDOW))
GType wintc_dpa_desktop_window_get_type(void) G_GNUC_CONST;
};
#endif

View File

@@ -14,6 +14,14 @@ enum
PROP_MONITOR = 1
};
//
// PRIVATE STRUCTURES
//
typedef struct _WinTCDpaDesktopWindowPrivate
{
GdkMonitor* monitor;
} WinTCDpaDesktopWindowPrivate;
//
// FORWARD DECLARATIONS
//
@@ -43,10 +51,11 @@ static void window_setup_x11(
//
// GTK TYPE DEFINITION & CTORS
//
G_DEFINE_TYPE(
G_DEFINE_TYPE_WITH_CODE(
WinTCDpaDesktopWindow,
wintc_dpa_desktop_window,
GTK_TYPE_APPLICATION_WINDOW
GTK_TYPE_APPLICATION_WINDOW,
G_ADD_PRIVATE(WinTCDpaDesktopWindow)
)
static void wintc_dpa_desktop_window_class_init(
@@ -102,12 +111,15 @@ static void wintc_dpa_desktop_window_get_property(
GParamSpec* pspec
)
{
WinTCDpaDesktopWindow* wnd = WINTC_DPA_DESKTOP_WINDOW(object);
WinTCDpaDesktopWindowPrivate* priv =
wintc_dpa_desktop_window_get_instance_private(
WINTC_DPA_DESKTOP_WINDOW(object)
);
switch (prop_id)
{
case PROP_MONITOR:
g_value_set_object(value, wnd->monitor);
g_value_set_object(value, priv->monitor);
break;
default:
@@ -123,12 +135,15 @@ static void wintc_dpa_desktop_window_set_property(
GParamSpec* pspec
)
{
WinTCDpaDesktopWindow* wnd = WINTC_DPA_DESKTOP_WINDOW(object);
WinTCDpaDesktopWindowPrivate* priv =
wintc_dpa_desktop_window_get_instance_private(
WINTC_DPA_DESKTOP_WINDOW(object)
);
switch (prop_id)
{
case PROP_MONITOR:
wnd->monitor = g_value_get_object(value);
priv->monitor = g_value_get_object(value);
break;
default:
@@ -144,11 +159,14 @@ static void window_setup_wayland(
WinTCDpaDesktopWindow* wnd
)
{
WinTCDpaDesktopWindowPrivate* priv =
wintc_dpa_desktop_window_get_instance_private(wnd);
GtkWindow* window = GTK_WINDOW(wnd);
p_gtk_layer_init_for_window(window);
p_gtk_layer_set_layer(window, GTK_LAYER_SHELL_LAYER_BACKGROUND);
p_gtk_layer_set_monitor(window, wnd->monitor);
p_gtk_layer_set_monitor(window, priv->monitor);
for (int edge = 0; edge <= GTK_LAYER_SHELL_EDGE_BOTTOM; edge++)
{
@@ -163,9 +181,12 @@ static void window_setup_x11(
WinTCDpaDesktopWindow* wnd
)
{
WinTCDpaDesktopWindowPrivate* priv =
wintc_dpa_desktop_window_get_instance_private(wnd);
GdkRectangle geometry;
gdk_monitor_get_geometry(wnd->monitor, &geometry);
gdk_monitor_get_geometry(priv->monitor, &geometry);
gtk_window_move(GTK_WINDOW(wnd), geometry.x, geometry.y);
gtk_window_set_type_hint(GTK_WINDOW(wnd), GDK_WINDOW_TYPE_HINT_DESKTOP);

View File

@@ -145,6 +145,16 @@ void _wintc_ishext_view_refreshing(
WinTCIShextView* view
);
// WinTCShextPathInfo methods
//
void wintc_shext_path_info_demangle_uri(
WinTCShextPathInfo* path_info,
const gchar* uri
);
gchar* wintc_shext_path_info_get_as_single_path(
WinTCShextPathInfo* path_info
);
void wintc_shext_path_info_copy(
WinTCShextPathInfo* dst,
WinTCShextPathInfo* src

View File

@@ -258,6 +258,77 @@ void _wintc_ishext_view_refreshing(
);
}
void wintc_shext_path_info_demangle_uri(
WinTCShextPathInfo* path_info,
const gchar* uri
)
{
//
// Fun stuff! There's a bunch of 'special' shell stuff we cram into URIs
// that aren't strictly valid... but they make sense to us -- this function
// 'demangles' the special sauce back into a valid WinTCShextPathInfo
//
// This is useful for handling GApplication::open when you might expect to
// handle a path incoming from WinTC
//
wintc_shext_path_info_free_data(path_info);
//
// STEP 1: Check if this is a GUID path
//
const gchar* p_guid_str = strstr(uri, "::%7B");
if (p_guid_str)
{
const gchar* p_end_guid = strstr(p_guid_str, "%7D");
if (p_end_guid)
{
gchar* guid_escaped = wintc_substr(p_guid_str, p_end_guid + 3);
path_info->base_path =
g_uri_unescape_string(guid_escaped, NULL);
g_free(guid_escaped);
}
}
//
// STEP 2: Check if there's an extended path
//
const gchar* p_ext_delim = strstr(uri, "??");
if (p_ext_delim)
{
if (!path_info->base_path)
{
path_info->base_path =
wintc_substr(uri, p_ext_delim);
}
path_info->extended_path =
wintc_substr(p_ext_delim + 2, NULL);
}
}
gchar* wintc_shext_path_info_get_as_single_path(
WinTCShextPathInfo* path_info
)
{
if (path_info->extended_path)
{
return
g_strdup_printf(
"%s??%s",
path_info->base_path,
path_info->extended_path
);
}
return g_strdup(path_info->base_path);
}
void wintc_shext_path_info_copy(
WinTCShextPathInfo* dst,
WinTCShextPathInfo* src

View File

@@ -18,19 +18,26 @@ include(GNUInstallDirs)
include(../../packaging/cmake-inc/common/CMakeLists.txt)
include(../../packaging/cmake-inc/linking/CMakeLists.txt)
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
include(../../packaging/cmake-inc/resources/CMakeLists.txt)
wintc_resolve_library(glib-2.0 GLIB)
wintc_resolve_library(gtk+-3.0 GTK3)
wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
wintc_resolve_library(wintc-registry WINTC_REGISTRY)
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
wintc_resolve_library(wintc-shell WINTC_SHELL)
wintc_resolve_library(wintc-shelldpa WINTC_SHELLDPA)
wintc_resolve_library(wintc-shellext WINTC_SHELLEXT)
wintc_resolve_library(wintc-syscfg WINTC_SYSCFG)
wintc_compile_resources()
add_executable(
wintc-desktop
src/application.c
src/application.h
src/main.c
src/resources.c
src/settings.c
src/settings.h
src/window.c
@@ -50,7 +57,10 @@ target_include_directories(
PRIVATE ${GTK3_INCLUDE_DIRS}
PRIVATE ${WINTC_COMGTK_INCLUDE_DIRS}
PRIVATE ${WINTC_REGISTRY_INCLUDE_DIRS}
PRIVATE ${WINTC_SHCOMMON_INCLUDE_DIRS}
PRIVATE ${WINTC_SHELL_INCLUDE_DIRS}
PRIVATE ${WINTC_SHELLDPA_INCLUDE_DIRS}
PRIVATE ${WINTC_SHELLEXT_INCLUDE_DIRS}
PRIVATE ${WINTC_SYSCFG_INCLUDE_DIRS}
)
@@ -60,7 +70,10 @@ target_link_directories(
PRIVATE ${GTK3_LIBRARY_DIRS}
PRIVATE ${WINTC_COMGTK_LIBRARY_DIRS}
PRIVATE ${WINTC_REGISTRY_LIBRARY_DIRS}
PRIVATE ${WINTC_SHCOMMON_LIBRARY_DIRS}
PRIVATE ${WINTC_SHELL_LIBRARY_DIRS}
PRIVATE ${WINTC_SHELLDPA_LIBRARY_DIRS}
PRIVATE ${WINTC_SHELLEXT_LIBRARY_DIRS}
PRIVATE ${WINTC_SYSCFG_LIBRARY_DIRS}
)
@@ -70,7 +83,10 @@ target_link_libraries(
PRIVATE ${GTK3_LIBRARIES}
PRIVATE ${WINTC_COMGTK_LIBRARIES}
PRIVATE ${WINTC_REGISTRY_LIBRARIES}
PRIVATE ${WINTC_SHCOMMON_LIBRARIES}
PRIVATE ${WINTC_SHELL_LIBRARIES}
PRIVATE ${WINTC_SHELLDPA_LIBRARIES}
PRIVATE ${WINTC_SHELLEXT_LIBRARIES}
PRIVATE ${WINTC_SYSCFG_LIBRARIES}
)

View File

@@ -2,5 +2,8 @@ bt,rt:glib2
bt,rt:gtk3
bt,rt:wintc-comgtk
bt,rt:wintc-registry
bt,rt:wintc-shcommon
bt,rt:wintc-shell
bt,rt:wintc-shelldpa
bt,rt:wintc-shellext
bt,rt:wintc-syscfg

View File

@@ -1,7 +1,9 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shell.h>
#include <wintc/shelldpa.h>
#include <wintc/shellext.h>
#include "application.h"
#include "settings.h"
@@ -10,21 +12,21 @@
//
// GTK OOP CLASS/INSANCE DEFINITIONS
//
struct _WinTCDesktopApplicationClass
{
GtkApplicationClass __parent__;
};
struct _WinTCDesktopApplication
{
GtkApplication __parent__;
WinTCDesktopSettings* settings;
WinTCShextHost* shext_host;
};
//
// FORWARD DECLARATIONS
//
static void wintc_desktop_application_dispose(
GObject* object
);
static void wintc_desktop_application_activate(
GApplication* application
);
@@ -70,6 +72,9 @@ static void wintc_desktop_application_class_init(
)
{
GApplicationClass* application_class = G_APPLICATION_CLASS(klass);
GObjectClass* object_class = G_OBJECT_CLASS(klass);
object_class->dispose = wintc_desktop_application_dispose;
application_class->activate =
wintc_desktop_application_activate;
@@ -92,28 +97,21 @@ static void wintc_desktop_application_init(
}
//
// PUBLIC FUNCTIONS
// CLASS VIRTUAL METHODS
//
WinTCDesktopApplication* wintc_desktop_application_new(void)
static void wintc_desktop_application_dispose(
GObject* object
)
{
WinTCDesktopApplication* app;
WinTCDesktopApplication* desktop_app =
WINTC_DESKTOP_APPLICATION(object);
g_set_application_name("Desktop");
g_clear_object(&(desktop_app->shext_host));
app =
g_object_new(
wintc_desktop_application_get_type(),
"application-id", "uk.co.oddmatics.wintc.desktop",
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,
NULL
);
return app;
(G_OBJECT_CLASS(wintc_desktop_application_parent_class))
->dispose(object);
}
//
// CALLBACKS
//
static void wintc_desktop_application_activate(
GApplication* application
)
@@ -144,7 +142,9 @@ static void wintc_desktop_application_activate(
GtkWidget* wnd = wintc_desktop_window_new(
desktop_app,
monitor,
desktop_app->settings
desktop_app->settings,
gdk_monitor_is_primary(monitor) ?
desktop_app->shext_host : NULL
);
gtk_widget_show_all(wnd);
@@ -185,6 +185,9 @@ static void wintc_desktop_application_startup(
GApplication* application
)
{
WinTCDesktopApplication* desktop_app =
WINTC_DESKTOP_APPLICATION(application);
// Chain up for gtk init
//
G_APPLICATION_CLASS(wintc_desktop_application_parent_class)
@@ -197,4 +200,50 @@ static void wintc_desktop_application_startup(
g_critical("%s", "Failed to resolve display protocol APIs.");
g_application_quit(application);
}
// Install styles
//
GtkCssProvider* css_provider = gtk_css_provider_new();
gtk_css_provider_load_from_resource(
css_provider,
"/uk/oddmatics/wintc/desktop/appstyles_p.css"
);
gtk_style_context_add_provider_for_screen(
gdk_screen_get_default(),
GTK_STYLE_PROVIDER(css_provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
);
// Init shext host
//
desktop_app->shext_host = wintc_shext_host_new();
wintc_sh_init_builtin_extensions(desktop_app->shext_host);
wintc_shext_host_load_extensions(
desktop_app->shext_host,
WINTC_SHEXT_LOAD_DEFAULT,
NULL
);
}
//
// PUBLIC MEHTODS
//
WinTCDesktopApplication* wintc_desktop_application_new(void)
{
WinTCDesktopApplication* app;
g_set_application_name("Desktop");
app =
g_object_new(
wintc_desktop_application_get_type(),
"application-id", "uk.co.oddmatics.wintc.desktop",
"flags", G_APPLICATION_HANDLES_COMMAND_LINE,
NULL
);
return app;
}

View File

@@ -7,17 +7,15 @@
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCDesktopApplicationClass WinTCDesktopApplicationClass;
typedef struct _WinTCDesktopApplication WinTCDesktopApplication;
#define WINTC_TYPE_DESKTOP_APPLICATION (wintc_desktop_application_get_type())
#define WINTC_TYPE_DESKTOP_APPLICATION (wintc_desktop_application_get_type())
#define WINTC_DESKTOP_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_DESKTOP_APPLICATION, WinTCDesktopApplication))
#define WINTC_DESKTOP_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_DESKTOP_APPLICATION, WinTCDesktopApplicationClass))
#define IS_WINTC_DESKTOP_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_DESKTOP_APPLICATION))
#define IS_WINTC_DESKTOP_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_DESKTOP_APPLICATION))
#define WINTC_DESKTOP_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_DESKTOP_APPLICATION, WinTCDesktopApplicationClass))
GType wintc_desktop_application_get_type(void) G_GNUC_CONST;
G_DECLARE_FINAL_TYPE(
WinTCDesktopApplication,
wintc_desktop_application,
WINTC,
DESKTOP_APPLICATION,
GtkApplication
)
//
// PUBLIC FUNCTIONS

View File

@@ -0,0 +1,11 @@
/**
* APPLICATION PRIORITY STYLES -- DO NOT OVERUSE!!
**/
/**
* Default styles for the icon view
*/
iconview
{
background: transparent;
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/uk/oddmatics/wintc/desktop">
<file>appstyles_p.css</file>
</gresource>
</gresources>

View File

@@ -18,11 +18,6 @@ enum
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCDesktopSettingsClass
{
GObjectClass __parent__;
};
struct _WinTCDesktopSettings
{
GObject __parent__;

View File

@@ -6,17 +6,15 @@
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCDesktopSettingsClass WinTCDesktopSettingsClass;
typedef struct _WinTCDesktopSettings WinTCDesktopSettings;
#define WINTC_TYPE_DESKTOP_SETTINGS (wintc_desktop_settings_get_type())
#define WINTC_TYPE_DESKTOP_SETTINGS (wintc_desktop_settings_get_type())
#define WINTC_DESKTOP_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_DESKTOP_SETTINGS, WinTCDesktopSettings))
#define WINTC_DESKTOP_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_DESKTOP_SETTINGS, WinTCDesktopSettingsClass))
#define IS_WINTC_DESKTOP_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_DESKTOP_SETTINGS))
#define IS_WINTC_DESKTOP_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_DESKTOP_SETTINGS))
#define WINTC_DESKTOP_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WINTC_TYPE_DESKTOP_SETTINGS, WinTCDesktopSettingsClass))
GType wintc_desktop_settings_get_type(void) G_GNUC_CONST;
G_DECLARE_FINAL_TYPE(
WinTCDesktopSettings,
wintc_desktop_settings,
WINTC,
DESKTOP_SETTINGS,
GObject
)
//
// PUBLIC FUNCTIONS

View File

@@ -3,7 +3,10 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/comgtk.h>
#include <wintc/shcommon.h>
#include <wintc/shell.h>
#include <wintc/shelldpa.h>
#include <wintc/shellext.h>
#include <wintc/syscfg.h>
#include "application.h"
@@ -15,29 +18,10 @@
//
enum
{
PROP_SETTINGS = 1
};
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCDesktopWindowClass
{
WinTCDpaDesktopWindowClass __parent__;
};
struct _WinTCDesktopWindow
{
WinTCDpaDesktopWindow __parent__;
// Drawing-related
//
GdkPixbuf* pixbuf_wallpaper;
cairo_surface_t* surface_wallpaper;
// State
//
WinTCDesktopSettings* settings;
PROP_NULL,
PROP_SETTINGS,
PROP_SHEXT_HOST,
N_PROPERTIES
};
//
@@ -82,6 +66,39 @@ static void on_settings_notify_wallpaper_style(
gpointer user_data
);
//
// STATIC DATA
//
static GParamSpec* wintc_desktop_window_properties[N_PROPERTIES] = { 0 };
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
//
struct _WinTCDesktopWindow
{
WinTCDpaDesktopWindow __parent__;
// UI
//
GtkWidget* iconview_browser;
WinTCShIconViewBehaviour* behaviour_icons;
// Shell stuff
//
WinTCShBrowser* browser;
WinTCShFolderOptions* fldr_opts;
WinTCShextHost* shext_host;
// Drawing-related
//
GdkPixbuf* pixbuf_wallpaper;
cairo_surface_t* surface_wallpaper;
// State
//
WinTCDesktopSettings* settings;
};
//
// GTK TYPE DEFINITION & CTORS
//
@@ -104,16 +121,27 @@ static void wintc_desktop_window_class_init(
widget_class->draw = wintc_desktop_window_draw;
g_object_class_install_property(
object_class,
PROP_SETTINGS,
wintc_desktop_window_properties[PROP_SETTINGS] =
g_param_spec_object(
"settings",
"Settings",
"The shared desktop settings",
WINTC_TYPE_DESKTOP_SETTINGS,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
wintc_desktop_window_properties[PROP_SHEXT_HOST] =
g_param_spec_object(
"shext-host",
"ShextHost",
"The shell extension host object to use.",
WINTC_TYPE_SHEXT_HOST,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
);
g_object_class_install_properties(
object_class,
N_PROPERTIES,
wintc_desktop_window_properties
);
}
@@ -121,6 +149,13 @@ static void wintc_desktop_window_init(
WinTCDesktopWindow* self
)
{
self->iconview_browser = gtk_icon_view_new();
gtk_container_add(
GTK_CONTAINER(self),
self->iconview_browser
);
g_signal_connect(
self,
"map-event",
@@ -138,6 +173,52 @@ static void wintc_desktop_window_constructed(
{
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(object);
// If we have a shext host, then we can set up the browser
//
if (wnd->shext_host)
{
wnd->fldr_opts = wintc_sh_folder_options_new();
wintc_sh_folder_options_set_browse_in_same_window(
wnd->fldr_opts,
FALSE
);
wnd->browser =
wintc_sh_browser_new(
wnd->shext_host,
wnd->fldr_opts
);
wintc_sh_browser_set_behaviour_flags(
wnd->browser,
WINTC_SH_BROWSER_BEHAVIOUR_DONT_USE_SELF_EXE
);
wnd->behaviour_icons =
wintc_sh_icon_view_behaviour_new(
GTK_ICON_VIEW(wnd->iconview_browser),
wnd->browser
);
// Navigate to desktop
//
WinTCShextPathInfo path_info = { 0 };
path_info.base_path =
g_strdup(
wintc_sh_get_place_path(WINTC_SH_PLACE_DESKTOP)
);
wintc_sh_browser_set_location(
wnd->browser,
&path_info,
NULL
);
wintc_shext_path_info_free_data(&path_info);
}
g_signal_connect(
wnd->settings,
"notify::pixbuf-wallpaper",
@@ -160,6 +241,11 @@ static void wintc_desktop_window_dispose(
{
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(object);
g_clear_object(&(wnd->behaviour_icons));
g_clear_object(&(wnd->browser));
g_clear_object(&(wnd->fldr_opts));
g_clear_object(&(wnd->shext_host));
if (wnd->surface_wallpaper)
{
cairo_surface_destroy(g_steal_pointer(&(wnd->surface_wallpaper)));
@@ -184,6 +270,10 @@ static void wintc_desktop_window_set_property(
wnd->settings = g_value_get_object(value);
break;
case PROP_SHEXT_HOST:
wnd->shext_host = g_value_dup_object(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -195,8 +285,7 @@ static gboolean wintc_desktop_window_draw(
cairo_t* cr
)
{
WinTCDpaDesktopWindow* dpa_wnd = WINTC_DPA_DESKTOP_WINDOW(widget);
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(widget);
WinTCDesktopWindow* wnd = WINTC_DESKTOP_WINDOW(widget);
gint wnd_w = gtk_widget_get_allocated_width(widget);
gint wnd_h = gtk_widget_get_allocated_height(widget);
@@ -259,7 +348,11 @@ static gboolean wintc_desktop_window_draw(
// Rough watermark drawing
//
if (gdk_monitor_is_primary(dpa_wnd->monitor))
// NOTE: We assume that we're the primary monitor if we have a shext host
// passed in -- this is quite cheeky to do, until we properly deal
// with primary monitor business on Waheyland
//
if (wnd->shext_host)
{
static gchar* s_tag = NULL;
@@ -324,6 +417,13 @@ static gboolean wintc_desktop_window_draw(
cairo_show_text(cr, "Windows 'Total Conversion'");
}
// Draw the icon view
//
gtk_widget_draw(wnd->iconview_browser, cr);
// (GTK_WIDGET_CLASS(wintc_desktop_window_parent_class))
// ->draw(widget, cr);
return FALSE;
}
@@ -333,7 +433,8 @@ static gboolean wintc_desktop_window_draw(
GtkWidget* wintc_desktop_window_new(
WinTCDesktopApplication* app,
GdkMonitor* monitor,
WinTCDesktopSettings* settings
WinTCDesktopSettings* settings,
WinTCShextHost* shext_host
)
{
return GTK_WIDGET(
@@ -345,6 +446,7 @@ GtkWidget* wintc_desktop_window_new(
"monitor", monitor,
"resizable", FALSE,
"settings", settings,
"shext-host", shext_host,
NULL
)
);

View File

@@ -3,6 +3,8 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <wintc/shelldpa.h>
#include <wintc/shellext.h>
#include "application.h"
#include "settings.h"
@@ -10,17 +12,15 @@
//
// GTK OOP BOILERPLATE
//
typedef struct _WinTCDesktopWindowClass WinTCDesktopWindowClass;
typedef struct _WinTCDesktopWindow WinTCDesktopWindow;
#define WINTC_TYPE_DESKTOP_WINDOW (wintc_desktop_window_get_type())
#define WINTC_TYPE_DESKTOP_WINDOW (wintc_desktop_window_get_type())
#define WINTC_DESKTOP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WINTC_TYPE_DESKTOP_WINDOW, WinTCDesktopWindow))
#define WINTC_DESKTOP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WINTC_TYPE_DESKTOP_WINDOW, WinTCDesktopWindow))
#define IS_WINTC_DESKTOP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WINTC_TYPE_DESKTOP_WINDOW))
#define IS_WINTC_DESKTOP_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WINTC_TYPE_DESKTOP_WINDOW))
#define WINTC_DESKTOP_WINDOW_GET_CLASS(obj) (G_TYPE_CHECK_INSTANCE_GET_CLASS((obj), WINTC_TYPE_DESKTOP_WINDOW))
GType wintc_desktop_window_get_type(void) G_GNUC_CONST;
G_DECLARE_FINAL_TYPE(
WinTCDesktopWindow,
wintc_desktop_window,
WINTC,
DESKTOP_WINDOW,
WinTCDpaDesktopWindow
)
//
// PUBLIC FUNCTIONS
@@ -28,7 +28,8 @@ GType wintc_desktop_window_get_type(void) G_GNUC_CONST;
GtkWidget* wintc_desktop_window_new(
WinTCDesktopApplication* app,
GdkMonitor* monitor,
WinTCDesktopSettings* settings
WinTCDesktopSettings* settings,
WinTCShextHost* shext_host
);
#endif

View File

@@ -24,8 +24,9 @@ struct _WinTCExplorerApplication
// Application state
//
WinTCExplorerLoader* exp_loader;
WinTCShextHost* shext_host;
WinTCExplorerLoader* exp_loader;
WinTCShFolderOptions* fldr_opts;
WinTCShextHost* shext_host;
};
//
@@ -132,6 +133,7 @@ static void wintc_explorer_application_dispose(
WINTC_EXPLORER_APPLICATION(object);
g_clear_object(&(explorer_app->shext_host));
g_clear_object(&(explorer_app->fldr_opts));
g_clear_object(&(explorer_app->exp_loader));
(G_OBJECT_CLASS(wintc_explorer_application_parent_class))
@@ -149,6 +151,7 @@ static void wintc_explorer_application_activate(
wintc_explorer_window_new(
explorer_app,
explorer_app->shext_host,
explorer_app->fldr_opts,
explorer_app->exp_loader,
NULL
);
@@ -237,6 +240,7 @@ static void wintc_explorer_application_open(
GtkWidget* wnd = wintc_explorer_window_new(
explorer_app,
explorer_app->shext_host,
explorer_app->fldr_opts,
explorer_app->exp_loader,
uri
);
@@ -279,6 +283,10 @@ static void wintc_explorer_application_startup(
WINTC_SHEXT_LOAD_DEFAULT,
NULL
);
// Create folder options
//
explorer_app->fldr_opts = wintc_sh_folder_options_new();
}
//

View File

@@ -23,10 +23,13 @@
//
enum
{
PROP_SHEXT_HOST = 1,
PROP_NULL,
PROP_SHEXT_HOST,
PROP_FOLDER_OPTIONS,
PROP_EXPLORER_LOADER,
PROP_INITIAL_PATH,
PROP_ACTIVE_SIDEBAR
PROP_ACTIVE_SIDEBAR,
N_PROPERTIES
};
enum
@@ -150,7 +153,8 @@ static GActionEntry s_window_actions[] = {
}
};
static gint wintc_explorer_window_signals[N_SIGNALS] = { 0 };
static GParamSpec* wintc_explorer_window_properties[N_PROPERTIES] = { 0 };
static gint wintc_explorer_window_signals[N_SIGNALS] = { 0 };
//
// GTK OOP CLASS/INSTANCE DEFINITIONS
@@ -166,8 +170,9 @@ struct _WinTCExplorerWindow
// Shell stuff
//
WinTCShBrowser* browser;
WinTCShextHost* shext_host;
WinTCShBrowser* browser;
WinTCShFolderOptions* fldr_opts;
WinTCShextHost* shext_host;
// State
//
@@ -223,50 +228,51 @@ static void wintc_explorer_window_class_init(
object_class->get_property = wintc_explorer_window_get_property;
object_class->set_property = wintc_explorer_window_set_property;
g_object_class_install_property(
object_class,
PROP_SHEXT_HOST,
wintc_explorer_window_properties[PROP_SHEXT_HOST] =
g_param_spec_object(
"shext-host",
"ShextHost",
"The shell extension host object to use.",
WINTC_TYPE_SHEXT_HOST,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
g_object_class_install_property(
object_class,
PROP_EXPLORER_LOADER,
);
wintc_explorer_window_properties[PROP_FOLDER_OPTIONS] =
g_param_spec_object(
"folder-options",
"FolderOptions",
"The folder options object to use",
WINTC_TYPE_SH_FOLDER_OPTIONS,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
);
wintc_explorer_window_properties[PROP_EXPLORER_LOADER] =
g_param_spec_object(
"explorer-loader",
"ExplorerLoader",
"The explorer sidebar and toolbar loader host object to use.",
WINTC_TYPE_EXPLORER_LOADER,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
g_object_class_install_property(
object_class,
PROP_INITIAL_PATH,
);
wintc_explorer_window_properties[PROP_INITIAL_PATH] =
g_param_spec_string(
"initial-path",
"InitialPath",
"The initial path for the window to open.",
NULL,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
)
);
g_object_class_install_property(
object_class,
PROP_ACTIVE_SIDEBAR,
);
wintc_explorer_window_properties[PROP_ACTIVE_SIDEBAR] =
g_param_spec_string(
"active-sidebar",
"ActiveSidebar",
"The currently active sidebar.",
NULL,
G_PARAM_READWRITE
)
);
g_object_class_install_properties(
object_class,
N_PROPERTIES,
wintc_explorer_window_properties
);
wintc_explorer_window_signals[SIGNAL_LOCATION_CHANGED] =
@@ -414,6 +420,11 @@ static void wintc_explorer_window_constructed(
return;
}
if (!wnd->fldr_opts)
{
wnd->fldr_opts = wintc_sh_folder_options_new();
}
// Handle initial path
//
if (!wnd->initial_path)
@@ -449,6 +460,7 @@ static void wintc_explorer_window_dispose(
g_clear_object(&(wnd->behaviour_icons));
g_clear_object(&(wnd->browser));
g_clear_object(&(wnd->fldr_opts));
g_clear_object(&(wnd->shext_host));
g_clear_object(&(wnd->iconview_browser));
@@ -512,13 +524,31 @@ static void wintc_explorer_window_set_property(
wnd->shext_host = g_value_dup_object(value);
break;
case PROP_FOLDER_OPTIONS:
wnd->fldr_opts = g_value_dup_object(value);
break;
case PROP_EXPLORER_LOADER:
wnd->loader = g_value_dup_object(value);
break;
case PROP_INITIAL_PATH:
wnd->initial_path = g_value_dup_string(value);
{
// FIXME: We don't handle extended paths yet!
//
WinTCShextPathInfo path_info;
wintc_shext_path_info_demangle_uri(
&path_info,
g_value_get_string(value)
);
wnd->initial_path = path_info.base_path;
path_info.base_path = NULL;
wintc_shext_path_info_free_data(&path_info);
break;
}
case PROP_ACTIVE_SIDEBAR:
// Check if this is a nothing burger
@@ -599,6 +629,7 @@ static void wintc_explorer_window_set_property(
GtkWidget* wintc_explorer_window_new(
WinTCExplorerApplication* app,
WinTCShextHost* shext_host,
WinTCShFolderOptions* fldr_opts,
WinTCExplorerLoader* loader,
const gchar* initial_path
)
@@ -608,6 +639,7 @@ GtkWidget* wintc_explorer_window_new(
WINTC_TYPE_EXPLORER_WINDOW,
"application", GTK_APPLICATION(app),
"shext-host", shext_host,
"folder-options", fldr_opts,
"explorer-loader", loader,
"initial-path", initial_path,
NULL
@@ -947,7 +979,11 @@ static void switch_mode_to(
// Set up shell browser
//
wnd->browser = wintc_sh_browser_new(wnd->shext_host);
wnd->browser =
wintc_sh_browser_new(
wnd->shext_host,
wnd->fldr_opts
);
g_signal_connect(
wnd->browser,

View File

@@ -40,6 +40,7 @@ GType wintc_explorer_window_get_type(void) G_GNUC_CONST;
GtkWidget* wintc_explorer_window_new(
WinTCExplorerApplication* app,
WinTCShextHost* shext_host,
WinTCShFolderOptions* fldr_opts,
WinTCExplorerLoader* loader,
const gchar* initial_path
);