build: add -ldl linker flag, recursive source discovery, and API test targets to Makefile

This commit is contained in:
2026-02-07 12:04:52 +00:00
parent 8e86b2d106
commit cd9e55dc64
181 changed files with 20646 additions and 7198 deletions
+57
View File
@@ -0,0 +1,57 @@
/*
* DWN - Desktop Window Manager
* Built-in Layout Registration
*/
#ifndef BUILTIN_LAYOUTS_H
#define BUILTIN_LAYOUTS_H
#include "plugins/layout_plugin.h"
#include "dwn.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize and register all built-in layouts.
* Called during DWN startup.
*/
bool wm_layouts_builtin_init(void);
/**
* Get a layout plugin by legacy LayoutType.
*/
LayoutPlugin* wm_layout_get_by_type(LayoutManager *mgr, LayoutType type);
/**
* Bridge function to arrange a workspace using the plugin system.
*/
bool wm_layout_arrange_workspace(LayoutManager *mgr, int workspace, LayoutType type);
/**
* Get symbol for a layout type.
*/
const char* wm_layout_get_symbol_for_type(LayoutType type);
/**
* Get name for a layout type.
*/
const char* wm_layout_get_name_for_type(LayoutType type);
/**
* Get LayoutType from name.
*/
LayoutType wm_layout_type_from_name(const char *name);
/* External layout interface getters */
const LayoutPluginInterface* wm_layout_tiling_get_interface(void);
const LayoutPluginInterface* wm_layout_floating_get_interface(void);
const LayoutPluginInterface* wm_layout_monocle_get_interface(void);
const LayoutPluginInterface* wm_layout_grid_get_interface(void);
#ifdef __cplusplus
}
#endif
#endif /* BUILTIN_LAYOUTS_H */
+365
View File
@@ -0,0 +1,365 @@
/*
* DWN - Desktop Window Manager
* Layout Plugin Interface
*/
#ifndef LAYOUT_PLUGIN_H
#define LAYOUT_PLUGIN_H
#include "core/wm_types.h"
#include "core/wm_client.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Layout Plugin API Version
*============================================================================*/
#define WM_LAYOUT_PLUGIN_API_VERSION 1
/*==============================================================================
* Forward Declarations
*============================================================================*/
typedef struct LayoutPlugin LayoutPlugin;
typedef struct LayoutContext LayoutContext;
/*==============================================================================
* Layout Geometry
*============================================================================*/
/**
* Layout geometry for a single client.
*/
typedef struct {
int x, y;
int width, height;
bool floating; /* If true, layout doesn't manage this client */
bool fullscreen; /* If true, client should be fullscreen */
bool hidden; /* If true, client should be hidden */
} WmLayoutGeometry;
/**
* Work area for layout calculations.
*/
typedef struct {
int x, y;
int width, height;
int padding_top;
int padding_bottom;
int padding_left;
int padding_right;
int gap;
} WmLayoutWorkArea;
/*==============================================================================
* Layout Configuration
*============================================================================*/
/**
* Layout configuration parameter.
*/
typedef struct {
const char *name;
const char *description;
union {
int int_value;
float float_value;
bool bool_value;
const char *string_value;
} default_value;
enum {
WM_LAYOUT_PARAM_INT,
WM_LAYOUT_PARAM_FLOAT,
WM_LAYOUT_PARAM_BOOL,
WM_LAYOUT_PARAM_STRING,
WM_LAYOUT_PARAM_CHOICE
} type;
/* For PARAM_CHOICE */
const char **choices;
int num_choices;
} WmLayoutParameter;
/**
* Layout configuration instance.
*/
typedef struct {
WmLayoutParameter *parameters;
int num_parameters;
void *user_data; /* Plugin can store parsed config here */
} WmLayoutConfig;
/*==============================================================================
* Layout State
*============================================================================*/
/**
* Opaque layout state per workspace.
* Layout plugins can store workspace-specific state here.
*/
typedef struct WmLayoutState WmLayoutState;
/*==============================================================================
* Layout Context
*============================================================================*/
/**
* Context passed to layout operations.
*/
struct LayoutContext {
/* Workspace info */
WmWorkspaceId workspace;
WmLayoutWorkArea work_area;
/* Client counts */
int client_count;
int master_count;
int stack_count;
/* Layout parameters */
float master_ratio;
int master_count_target;
int gap;
/* Configuration */
WmLayoutConfig *config;
/* Layout state (managed by plugin) */
WmLayoutState *state;
/* User data (for plugin use) */
void *user_data;
};
/*==============================================================================
* Layout Plugin Interface
*============================================================================*/
/**
* Layout plugin interface vtable.
* All layouts must implement these functions.
*/
typedef struct {
/* Version check */
int api_version;
/* Metadata */
const char *name;
const char *description;
const char *author;
const char *version;
/* Configuration */
WmLayoutParameter *parameters;
int num_parameters;
/* Lifecycle */
bool (*init)(LayoutPlugin *plugin);
void (*shutdown)(LayoutPlugin *plugin);
/* State management */
WmLayoutState* (*state_create)(LayoutPlugin *plugin, WmWorkspaceId workspace);
void (*state_destroy)(LayoutPlugin *plugin, WmLayoutState *state);
void (*state_reset)(LayoutPlugin *plugin, WmLayoutState *state);
/* Configuration */
bool (*config_parse)(LayoutPlugin *plugin, WmLayoutConfig *config,
const char *key, const char *value);
void (*config_apply)(LayoutPlugin *plugin, WmLayoutConfig *config);
/* Layout calculation */
bool (*arrange)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient **clients, int num_clients,
WmLayoutGeometry *geometries);
/* Client operations */
void (*client_added)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient *client);
void (*client_removed)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient *client);
void (*client_floating_changed)(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient *client, bool floating);
/* Layout manipulation */
void (*inc_master)(LayoutPlugin *plugin, LayoutContext *ctx, int delta);
void (*set_master_ratio)(LayoutPlugin *plugin, LayoutContext *ctx, float ratio);
void (*set_master_count)(LayoutPlugin *plugin, LayoutContext *ctx, int count);
void (*swap_master)(LayoutPlugin *plugin, LayoutContext *ctx);
void (*rotate)(LayoutPlugin *plugin, LayoutContext *ctx, bool clockwise);
/* Mouse resizing support */
void (*resize_master)(LayoutPlugin *plugin, LayoutContext *ctx,
int x, int y, int *new_master_count, float *new_ratio);
} LayoutPluginInterface;
/*==============================================================================
* Layout Plugin Structure
*============================================================================*/
/**
* Layout plugin instance.
*/
struct LayoutPlugin {
/* Interface vtable */
const LayoutPluginInterface *interface;
/* Plugin handle (for dynamic loading) */
void *handle;
/* Plugin path */
char *path;
/* Enabled state */
bool enabled;
/* Global configuration */
WmLayoutConfig config;
/* Per-workspace states */
WmLayoutState **workspace_states;
int num_workspaces;
/* Plugin-private data */
void *user_data;
};
/*==============================================================================
* Layout Manager
*============================================================================*/
/**
* Layout manager handles all loaded layouts.
*/
typedef struct LayoutManager LayoutManager;
/**
* Get the global layout manager.
*/
LayoutManager* wm_layout_manager_get(void);
/**
* Initialize the layout manager.
*/
bool wm_layout_manager_init(void);
/**
* Shutdown the layout manager.
*/
void wm_layout_manager_shutdown(void);
/**
* Register a layout plugin.
*/
bool wm_layout_manager_register(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Unregister a layout plugin.
*/
void wm_layout_manager_unregister(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Load a layout plugin from a file.
*/
LayoutPlugin* wm_layout_manager_load(LayoutManager *mgr, const char *path);
/**
* Unload a layout plugin.
*/
void wm_layout_manager_unload(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Get a loaded layout by name.
*/
LayoutPlugin* wm_layout_manager_get_layout(LayoutManager *mgr, const char *name);
/**
* Get the default layout.
*/
LayoutPlugin* wm_layout_manager_get_default(LayoutManager *mgr);
/**
* Set the default layout.
*/
void wm_layout_manager_set_default(LayoutManager *mgr, LayoutPlugin *plugin);
/**
* Get list of available layouts.
*/
const char** wm_layout_manager_list(LayoutManager *mgr, int *count);
/*==============================================================================
* Layout Operations
*============================================================================*/
/**
* Apply a layout to a workspace.
*/
bool wm_layout_arrange(LayoutPlugin *plugin, WmWorkspaceId workspace);
/**
* Apply layout to specific clients.
*/
bool wm_layout_arrange_clients(LayoutPlugin *plugin, LayoutContext *ctx,
AbstractClient **clients, int num_clients);
/**
* Create a layout context for a workspace.
*/
bool wm_layout_context_init(LayoutContext *ctx, WmWorkspaceId workspace);
/**
* Clean up a layout context.
*/
void wm_layout_context_cleanup(LayoutContext *ctx);
/*==============================================================================
* Built-in Layouts
*============================================================================*/
/* Tiling layout */
extern const LayoutPluginInterface wm_layout_tiling;
/* Floating layout */
extern const LayoutPluginInterface wm_layout_floating;
/* Monocle (maximized) layout */
extern const LayoutPluginInterface wm_layout_monocle;
/* Grid layout */
extern const LayoutPluginInterface wm_layout_grid;
/* Spiral layout */
extern const LayoutPluginInterface wm_layout_spiral;
/* Dwindle layout */
extern const LayoutPluginInterface wm_layout_dwindle;
/*==============================================================================
* Plugin Entry Point
*============================================================================*/
/**
* Layout plugins must export this function.
*/
typedef const LayoutPluginInterface* (*LayoutPluginEntryFunc)(void);
#define WM_LAYOUT_PLUGIN_ENTRY "wm_layout_plugin_entry"
/*==============================================================================
* Helper Macros
*============================================================================*/
#define WM_LAYOUT_REGISTER(name, iface) \
__attribute__((unused)) static const LayoutPluginInterface* wm_layout_plugin_entry(void) { return &(iface); }
/* Typedef for built-in layout getters */
typedef const LayoutPluginInterface* (*WmLayoutBuiltinFunc)(void);
#ifdef __cplusplus
}
#endif
#endif /* LAYOUT_PLUGIN_H */
+435
View File
@@ -0,0 +1,435 @@
/*
* DWN - Desktop Window Manager
* Widget Plugin Interface
* Panel components (taskbar, clock, workspaces, etc.)
*/
#ifndef WIDGET_PLUGIN_H
#define WIDGET_PLUGIN_H
#include "core/wm_types.h"
#include "core/wm_client.h"
#ifdef __cplusplus
extern "C" {
#endif
/*==============================================================================
* Widget Plugin API Version
*============================================================================*/
#define WM_WIDGET_PLUGIN_API_VERSION 1
/*==============================================================================
* Forward Declarations
*============================================================================*/
typedef struct WidgetPlugin WidgetPlugin;
typedef struct WidgetContext WidgetContext;
typedef struct WidgetInstance WidgetInstance;
/*==============================================================================
* Widget Position
*============================================================================*/
typedef enum {
WM_WIDGET_POSITION_LEFT,
WM_WIDGET_POSITION_CENTER,
WM_WIDGET_POSITION_RIGHT
} WmWidgetPosition;
/*==============================================================================
* Widget Size Constraints
*============================================================================*/
typedef struct {
int min_width;
int min_height;
int max_width;
int max_height;
bool expand_horizontal; /* Take available horizontal space */
bool expand_vertical; /* Take available vertical space */
} WmWidgetConstraints;
/*==============================================================================
* Widget Geometry
*============================================================================*/
typedef struct {
int x, y;
int width, height;
} WmWidgetGeometry;
/*==============================================================================
* Widget State
*============================================================================*/
typedef enum {
WM_WIDGET_STATE_NORMAL = 0,
WM_WIDGET_STATE_HOVERED = (1 << 0),
WM_WIDGET_STATE_PRESSED = (1 << 1),
WM_WIDGET_STATE_ACTIVE = (1 << 2),
WM_WIDGET_STATE_DISABLED = (1 << 3),
WM_WIDGET_STATE_HIDDEN = (1 << 4),
WM_WIDGET_STATE_URGENT = (1 << 5)
} WmWidgetState;
/*==============================================================================
* Widget Context
*============================================================================*/
struct WidgetContext {
/* Position in panel */
WmWidgetPosition position;
/* Geometry */
WmWidgetGeometry geometry;
WmWidgetConstraints constraints;
/* Panel info */
WmRect panel_geometry;
bool is_top_panel;
/* Rendering context */
void *render_context; /* Backend-specific (X11 GC, cairo, etc.) */
WmColor bg_color;
WmColor fg_color;
/* Font */
void *font; /* Opaque font handle */
int font_size;
/* User data */
void *user_data;
};
/*==============================================================================
* Widget Event Types
*============================================================================*/
typedef enum {
WM_WIDGET_EVENT_NONE,
WM_WIDGET_EVENT_MOUSE_ENTER,
WM_WIDGET_EVENT_MOUSE_LEAVE,
WM_WIDGET_EVENT_MOUSE_MOVE,
WM_WIDGET_EVENT_BUTTON_PRESS,
WM_WIDGET_EVENT_BUTTON_RELEASE,
WM_WIDGET_EVENT_SCROLL,
WM_WIDGET_EVENT_KEY_PRESS,
WM_WIDGET_EVENT_FOCUS_IN,
WM_WIDGET_EVENT_FOCUS_OUT,
WM_WIDGET_EVENT_UPDATE, /* Request to redraw */
WM_WIDGET_EVENT_CONFIGURE, /* Size/position changed */
WM_WIDGET_EVENT_DATA_CHANGED /* External data changed */
} WmWidgetEventType;
typedef struct {
WmWidgetEventType type;
WmWidgetGeometry widget_geometry;
union {
struct { int x, y; } point;
struct { int button; int x, y; } button;
struct { int delta; bool horizontal; } scroll;
struct { unsigned int keycode; unsigned int state; } key;
} data;
} WmWidgetEvent;
/*==============================================================================
* Widget Configuration
*============================================================================*/
typedef struct {
const char *name;
const char *value;
} WmWidgetConfigOption;
typedef struct {
WmWidgetConfigOption *options;
int num_options;
} WmWidgetConfig;
/*==============================================================================
* Widget Information
*============================================================================*/
typedef struct {
const char *id; /* Unique identifier */
const char *name; /* Display name */
const char *description; /* Description */
const char *author; /* Author */
const char *version; /* Version */
/* Default constraints */
WmWidgetConstraints default_constraints;
/* Default position */
WmWidgetPosition default_position;
/* Configuration schema */
const char **config_options; /* List of accepted config option names */
int num_config_options;
} WmWidgetInfo;
/*==============================================================================
* Widget Plugin Interface
*============================================================================*/
typedef struct {
/* Version check */
int api_version;
/* Metadata */
WmWidgetInfo info;
/* Lifecycle */
bool (*init)(WidgetPlugin *plugin);
void (*shutdown)(WidgetPlugin *plugin);
/* Instance management */
WidgetInstance* (*instance_create)(WidgetPlugin *plugin,
const WmWidgetConfig *config);
void (*instance_destroy)(WidgetPlugin *plugin, WidgetInstance *instance);
void (*instance_configure)(WidgetPlugin *plugin, WidgetInstance *instance,
const WmWidgetConfig *config);
/* Rendering */
void (*render)(WidgetPlugin *plugin, WidgetInstance *instance,
WidgetContext *ctx);
/* Event handling */
bool (*handle_event)(WidgetPlugin *plugin, WidgetInstance *instance,
const WmWidgetEvent *event);
/* Update notification */
void (*update)(WidgetPlugin *plugin, WidgetInstance *instance);
/* Size calculation */
void (*get_preferred_size)(WidgetPlugin *plugin, WidgetInstance *instance,
int *width, int *height);
} WidgetPluginInterface;
/*==============================================================================
* Widget Instance
*============================================================================*/
struct WidgetInstance {
/* Plugin that created this instance */
WidgetPlugin *plugin;
/* Instance state */
WmWidgetState state;
WmWidgetGeometry geometry;
WmWidgetConstraints constraints;
/* Configuration */
WmWidgetConfig config;
/* Context */
WidgetContext *context;
/* Plugin-private data */
void *user_data;
/* Linked list for panel */
WidgetInstance *next;
WidgetInstance *prev;
};
/*==============================================================================
* Widget Plugin Structure
*============================================================================*/
struct WidgetPlugin {
/* Interface vtable */
const WidgetPluginInterface *interface;
/* Plugin handle (for dynamic loading) */
void *handle;
/* Plugin path */
char *path;
/* Enabled state */
bool enabled;
/* Instances */
WidgetInstance *instances;
int instance_count;
/* Plugin-private data */
void *user_data;
};
/*==============================================================================
* Widget Manager
*============================================================================*/
typedef struct WidgetManager WidgetManager;
/**
* Get the global widget manager.
*/
WidgetManager* wm_widget_manager_get(void);
/**
* Initialize the widget manager.
*/
bool wm_widget_manager_init(void);
/**
* Shutdown the widget manager.
*/
void wm_widget_manager_shutdown(void);
/**
* Register a widget plugin.
*/
bool wm_widget_manager_register(WidgetManager *mgr, WidgetPlugin *plugin);
/**
* Unregister a widget plugin.
*/
void wm_widget_manager_unregister(WidgetManager *mgr, WidgetPlugin *plugin);
/**
* Load a widget plugin from a file.
*/
WidgetPlugin* wm_widget_manager_load(WidgetManager *mgr, const char *path);
/**
* Unload a widget plugin.
*/
void wm_widget_manager_unload(WidgetManager *mgr, WidgetPlugin *plugin);
/**
* Get a loaded widget by ID.
*/
WidgetPlugin* wm_widget_manager_get_widget(WidgetManager *mgr, const char *id);
/**
* Get list of available widgets.
*/
const char** wm_widget_manager_list(WidgetManager *mgr, int *count);
/*==============================================================================
* Widget Instance Operations
*============================================================================*/
/**
* Create a widget instance.
*/
WidgetInstance* wm_widget_create_instance(WidgetPlugin *plugin,
const WmWidgetConfig *config);
/**
* Destroy a widget instance.
*/
void wm_widget_destroy_instance(WidgetInstance *instance);
/**
* Render a widget instance.
*/
void wm_widget_render(WidgetInstance *instance, WidgetContext *ctx);
/**
* Send an event to a widget instance.
*/
bool wm_widget_send_event(WidgetInstance *instance, const WmWidgetEvent *event);
/**
* Update a widget instance (request redraw).
*/
void wm_widget_update(WidgetInstance *instance);
/**
* Get preferred size for a widget instance.
*/
void wm_widget_get_preferred_size(WidgetInstance *instance,
int *width, int *height);
/*==============================================================================
* Widget Panel Integration
*============================================================================*/
typedef struct WidgetPanel WidgetPanel;
/**
* Create a widget panel (container for widget instances).
*/
WidgetPanel* wm_widget_panel_create(void);
/**
* Destroy a widget panel.
*/
void wm_widget_panel_destroy(WidgetPanel *panel);
/**
* Add a widget instance to a panel.
*/
void wm_widget_panel_add(WidgetPanel *panel, WidgetInstance *instance,
WmWidgetPosition position);
/**
* Remove a widget instance from a panel.
*/
void wm_widget_panel_remove(WidgetPanel *panel, WidgetInstance *instance);
/**
* Arrange widgets in a panel.
*/
void wm_widget_panel_arrange(WidgetPanel *panel, const WmRect *panel_geometry);
/**
* Render all widgets in a panel.
*/
void wm_widget_panel_render(WidgetPanel *panel);
/**
* Handle mouse event in a panel.
*/
bool wm_widget_panel_handle_event(WidgetPanel *panel,
const WmWidgetEvent *event);
/*==============================================================================
* Built-in Widgets
*============================================================================*/
/* Workspace switcher widget */
extern const WidgetPluginInterface wm_widget_workspaces;
/* Taskbar widget */
extern const WidgetPluginInterface wm_widget_taskbar;
/* Clock widget */
extern const WidgetPluginInterface wm_widget_clock;
/* System tray widget */
extern const WidgetPluginInterface wm_widget_systray;
/* CPU/Memory monitor widget */
extern const WidgetPluginInterface wm_widget_system_stats;
/* News ticker widget */
extern const WidgetPluginInterface wm_widget_news;
/*==============================================================================
* Plugin Entry Point
*============================================================================*/
typedef const WidgetPluginInterface* (*WidgetPluginEntryFunc)(void);
#define WM_WIDGET_PLUGIN_ENTRY "wm_widget_plugin_entry"
/*==============================================================================
* Helper Macros
*============================================================================*/
#define WM_WIDGET_REGISTER(name, iface) \
static const WidgetPluginInterface* wm_widget_plugin_entry(void) { return &(iface); }
#ifdef __cplusplus
}
#endif
#endif /* WIDGET_PLUGIN_H */