524 lines
14 KiB
C
524 lines
14 KiB
C
|
|
/*
|
||
|
|
* DWN - Desktop Window Manager
|
||
|
|
* Abstract Client Interface
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef WM_CLIENT_H
|
||
|
|
#define WM_CLIENT_H
|
||
|
|
|
||
|
|
#include "core/wm_types.h"
|
||
|
|
#include "core/wm_string.h"
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
extern "C" {
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/* Forward declarations */
|
||
|
|
typedef struct Client Client; /* Legacy client structure */
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Abstract Client Type
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
typedef struct AbstractClient AbstractClient;
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client State Flags
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
typedef enum {
|
||
|
|
WM_CLIENT_STATE_NORMAL = 0,
|
||
|
|
WM_CLIENT_STATE_FLOATING = (1 << 0),
|
||
|
|
WM_CLIENT_STATE_FULLSCREEN = (1 << 1),
|
||
|
|
WM_CLIENT_STATE_MAXIMIZED = (1 << 2),
|
||
|
|
WM_CLIENT_STATE_MINIMIZED = (1 << 3),
|
||
|
|
WM_CLIENT_STATE_URGENT = (1 << 4),
|
||
|
|
WM_CLIENT_STATE_STICKY = (1 << 5),
|
||
|
|
WM_CLIENT_STATE_HIDDEN = (1 << 6),
|
||
|
|
WM_CLIENT_STATE_FOCUS = (1 << 7),
|
||
|
|
WM_CLIENT_STATE_MAPPED = (1 << 8),
|
||
|
|
WM_CLIENT_STATE_MANAGED = (1 << 9),
|
||
|
|
WM_CLIENT_STATE_DESTROYING = (1 << 10)
|
||
|
|
} WmClientState;
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Window Type
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
typedef enum {
|
||
|
|
WM_CLIENT_TYPE_UNKNOWN = 0,
|
||
|
|
WM_CLIENT_TYPE_NORMAL,
|
||
|
|
WM_CLIENT_TYPE_DIALOG,
|
||
|
|
WM_CLIENT_TYPE_DOCK,
|
||
|
|
WM_CLIENT_TYPE_DESKTOP,
|
||
|
|
WM_CLIENT_TYPE_TOOLBAR,
|
||
|
|
WM_CLIENT_TYPE_MENU,
|
||
|
|
WM_CLIENT_TYPE_UTILITY,
|
||
|
|
WM_CLIENT_TYPE_SPLASH,
|
||
|
|
WM_CLIENT_TYPE_NOTIFICATION
|
||
|
|
} WmClientType;
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Lifecycle
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create an abstract client from a native window handle.
|
||
|
|
* This takes ownership of the native window.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_create(WmWindowHandle window, WmClientType type);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Destroy a client and release all associated resources.
|
||
|
|
*/
|
||
|
|
void wm_client_destroy(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if a client is valid (not NULL and not being destroyed).
|
||
|
|
*/
|
||
|
|
bool wm_client_is_valid(const AbstractClient *client);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Native Access (for compatibility during migration)
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the native window handle.
|
||
|
|
* Note: This should be avoided in backend-agnostic code.
|
||
|
|
*/
|
||
|
|
WmWindowHandle wm_client_get_window(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the native frame window handle (if reparented).
|
||
|
|
*/
|
||
|
|
WmWindowHandle wm_client_get_frame(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the legacy Client structure.
|
||
|
|
* Note: This is for gradual migration only.
|
||
|
|
*/
|
||
|
|
Client* wm_client_get_legacy(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create an abstract client wrapper around an existing legacy Client.
|
||
|
|
* Note: The abstract client does NOT own the legacy client.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_from_legacy(Client *client);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Identification
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the unique client ID.
|
||
|
|
*/
|
||
|
|
WmClientId wm_client_get_id(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client window type.
|
||
|
|
*/
|
||
|
|
WmClientType wm_client_get_type(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client window type.
|
||
|
|
*/
|
||
|
|
void wm_client_set_type(AbstractClient *client, WmClientType type);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client State
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the current state flags.
|
||
|
|
*/
|
||
|
|
WmClientState wm_client_get_state(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set state flags.
|
||
|
|
*/
|
||
|
|
void wm_client_set_state(AbstractClient *client, WmClientState state);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Add state flags.
|
||
|
|
*/
|
||
|
|
void wm_client_add_state(AbstractClient *client, WmClientState state);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Remove state flags.
|
||
|
|
*/
|
||
|
|
void wm_client_remove_state(AbstractClient *client, WmClientState state);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Toggle state flags.
|
||
|
|
*/
|
||
|
|
void wm_client_toggle_state(AbstractClient *client, WmClientState state);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if a specific state is set.
|
||
|
|
*/
|
||
|
|
bool wm_client_has_state(const AbstractClient *client, WmClientState state);
|
||
|
|
|
||
|
|
/* Convenience state checks */
|
||
|
|
static inline bool wm_client_is_floating(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_FLOATING);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_fullscreen(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_FULLSCREEN);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_maximized(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_MAXIMIZED);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_minimized(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_MINIMIZED);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_urgent(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_URGENT);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_sticky(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_STICKY);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_focused(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_FOCUS);
|
||
|
|
}
|
||
|
|
static inline bool wm_client_is_mapped(const AbstractClient *c) {
|
||
|
|
return c && wm_client_has_state(c, WM_CLIENT_STATE_MAPPED);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Geometry
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client geometry (position and size).
|
||
|
|
*/
|
||
|
|
WmRect wm_client_get_geometry(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client geometry.
|
||
|
|
*/
|
||
|
|
void wm_client_set_geometry(AbstractClient *client, const WmRect *geometry);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client position.
|
||
|
|
*/
|
||
|
|
WmPoint wm_client_get_position(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client position.
|
||
|
|
*/
|
||
|
|
void wm_client_set_position(AbstractClient *client, int x, int y);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client size.
|
||
|
|
*/
|
||
|
|
WmSize wm_client_get_size(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client size.
|
||
|
|
*/
|
||
|
|
void wm_client_set_size(AbstractClient *client, int width, int height);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the border width.
|
||
|
|
*/
|
||
|
|
int wm_client_get_border_width(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the border width.
|
||
|
|
*/
|
||
|
|
void wm_client_set_border_width(AbstractClient *client, int width);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Store previous geometry (for restore after maximize/fullscreen).
|
||
|
|
*/
|
||
|
|
void wm_client_save_geometry(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Restore previous geometry.
|
||
|
|
*/
|
||
|
|
void wm_client_restore_geometry(AbstractClient *client);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Workspace
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client's workspace ID.
|
||
|
|
*/
|
||
|
|
WmWorkspaceId wm_client_get_workspace(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client's workspace ID.
|
||
|
|
*/
|
||
|
|
void wm_client_set_workspace(AbstractClient *client, WmWorkspaceId workspace);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if the client is on a specific workspace.
|
||
|
|
*/
|
||
|
|
bool wm_client_is_on_workspace(const AbstractClient *client, WmWorkspaceId workspace);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Check if the client is visible on the current workspace.
|
||
|
|
*/
|
||
|
|
bool wm_client_is_visible_on_current(const AbstractClient *client);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Properties
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client title.
|
||
|
|
* Returns a reference to the internal string (do not free).
|
||
|
|
*/
|
||
|
|
const char* wm_client_get_title(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client title.
|
||
|
|
*/
|
||
|
|
void wm_client_set_title(AbstractClient *client, const char *title);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client class (application class).
|
||
|
|
*/
|
||
|
|
const char* wm_client_get_class(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client class.
|
||
|
|
*/
|
||
|
|
void wm_client_set_class(AbstractClient *client, const char *class_name);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client instance name.
|
||
|
|
*/
|
||
|
|
const char* wm_client_get_instance(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client instance name.
|
||
|
|
*/
|
||
|
|
void wm_client_set_instance(AbstractClient *client, const char *instance);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the client's taskbar color.
|
||
|
|
*/
|
||
|
|
WmColor wm_client_get_color(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the client's taskbar color.
|
||
|
|
*/
|
||
|
|
void wm_client_set_color(AbstractClient *client, WmColor color);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Actions
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Focus the client.
|
||
|
|
*/
|
||
|
|
void wm_client_focus(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Unfocus the client.
|
||
|
|
*/
|
||
|
|
void wm_client_unfocus(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Raise the client to the top of the stack.
|
||
|
|
*/
|
||
|
|
void wm_client_raise(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Lower the client to the bottom of the stack.
|
||
|
|
*/
|
||
|
|
void wm_client_lower(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Show/map the client window.
|
||
|
|
*/
|
||
|
|
void wm_client_show(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Hide/unmap the client window.
|
||
|
|
*/
|
||
|
|
void wm_client_hide(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Minimize the client.
|
||
|
|
*/
|
||
|
|
void wm_client_minimize(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Restore the client from minimized state.
|
||
|
|
*/
|
||
|
|
void wm_client_restore(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Close the client (politely request close).
|
||
|
|
*/
|
||
|
|
void wm_client_close(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Kill the client (forcefully terminate).
|
||
|
|
*/
|
||
|
|
void wm_client_kill(AbstractClient *client);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Management
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Reparent the client into a frame window.
|
||
|
|
*/
|
||
|
|
void wm_client_reparent(AbstractClient *client, WmWindowHandle frame);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Unreparent the client from its frame.
|
||
|
|
*/
|
||
|
|
void wm_client_unreparent(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Configure the client (apply size hints, constraints).
|
||
|
|
*/
|
||
|
|
void wm_client_configure(AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Apply size hints to constrain width/height.
|
||
|
|
*/
|
||
|
|
void wm_client_apply_size_hints(AbstractClient *client, int *width, int *height);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Move and resize a client.
|
||
|
|
*/
|
||
|
|
void wm_client_move_resize(AbstractClient *client, int x, int y, int width, int height);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client List Management
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the next client in the global list.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_get_next(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the previous client in the global list.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_get_prev(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the first client in the global list.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_get_first(void);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the last client in the global list.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_get_last(void);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the next client in MRU (Most Recently Used) order.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_get_next_mru(const AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the previous client in MRU order.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_get_prev_mru(const AbstractClient *client);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Lookup
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Find a client by its window handle.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_find_by_window(WmWindowHandle window);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Find a client by its frame handle.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_find_by_frame(WmWindowHandle frame);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Find a client by its ID.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_find_by_id(WmClientId id);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Iteration
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
typedef bool (*WmClientForeachFunc)(AbstractClient *client, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Iterate over all clients.
|
||
|
|
*/
|
||
|
|
void wm_client_foreach(WmClientForeachFunc func, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Iterate over clients on a specific workspace.
|
||
|
|
*/
|
||
|
|
void wm_client_foreach_on_workspace(WmWorkspaceId workspace,
|
||
|
|
WmClientForeachFunc func, void *user_data);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Count total clients.
|
||
|
|
*/
|
||
|
|
int wm_client_count(void);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Count clients on a specific workspace.
|
||
|
|
*/
|
||
|
|
int wm_client_count_on_workspace(WmWorkspaceId workspace);
|
||
|
|
|
||
|
|
/*==============================================================================
|
||
|
|
* Client Manager
|
||
|
|
*============================================================================*/
|
||
|
|
|
||
|
|
typedef struct WmClientManager WmClientManager;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the global client manager.
|
||
|
|
*/
|
||
|
|
WmClientManager* wm_client_manager_get(void);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Initialize the client manager.
|
||
|
|
*/
|
||
|
|
bool wm_client_manager_init(void);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Shutdown the client manager.
|
||
|
|
*/
|
||
|
|
void wm_client_manager_shutdown(void);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Register a client with the manager.
|
||
|
|
*/
|
||
|
|
void wm_client_manager_add(WmClientManager *mgr, AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Unregister a client from the manager.
|
||
|
|
*/
|
||
|
|
void wm_client_manager_remove(WmClientManager *mgr, AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Move a client to the front of the MRU list.
|
||
|
|
*/
|
||
|
|
void wm_client_manager_touch(WmClientManager *mgr, AbstractClient *client);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the focused client.
|
||
|
|
*/
|
||
|
|
AbstractClient* wm_client_manager_get_focused(const WmClientManager *mgr);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the focused client.
|
||
|
|
*/
|
||
|
|
void wm_client_manager_set_focused(WmClientManager *mgr, AbstractClient *client);
|
||
|
|
|
||
|
|
#ifdef __cplusplus
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#endif /* WM_CLIENT_H */
|