From abc09951e1fe1c80edadb64d46180d738788a56d Mon Sep 17 00:00:00 2001 From: kojima Date: Wed, 12 Sep 2001 21:43:42 +0000 Subject: [PATCH] begin wmspec stuff --- configure.ac | 6 +- configure.in | 6 +- src/Makefile.am | 2 + src/screen.c | 11 +- src/screen.h | 10 +- src/stacking.c | 2 + src/window.h | 5 + src/wmspec.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wmspec.h | 30 ++++ 9 files changed, 520 insertions(+), 8 deletions(-) create mode 100644 src/wmspec.c create mode 100644 src/wmspec.h diff --git a/configure.ac b/configure.ac index 48bd150a..dd6080ef 100644 --- a/configure.ac +++ b/configure.ac @@ -177,7 +177,7 @@ dnl Checks for header files. dnl ======================= AC_HEADER_SYS_WAIT AC_HEADER_TIME -AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h sys/types.h libintl.h sys/select.h poll.h malloc.h ctype.h stdlib.h string.h strings.h) +AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h sys/types.h libintl.h sys/select.h poll.h malloc.h ctype.h string.h strings.h) @@ -775,6 +775,10 @@ dnl End of Graphic Format Libraries dnl ============================================== +dnl +dnl stdlib.h is checked here, because of conflict in jpeglib.h +AC_CHECK_HEADERS(stdlib.h) + # AC_PREFIX_PROGRAM(wmaker) dnl Support for PIXMAPDIR option diff --git a/configure.in b/configure.in index 48bd150a..dd6080ef 100644 --- a/configure.in +++ b/configure.in @@ -177,7 +177,7 @@ dnl Checks for header files. dnl ======================= AC_HEADER_SYS_WAIT AC_HEADER_TIME -AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h sys/types.h libintl.h sys/select.h poll.h malloc.h ctype.h stdlib.h string.h strings.h) +AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h sys/time.h sys/types.h libintl.h sys/select.h poll.h malloc.h ctype.h string.h strings.h) @@ -775,6 +775,10 @@ dnl End of Graphic Format Libraries dnl ============================================== +dnl +dnl stdlib.h is checked here, because of conflict in jpeglib.h +AC_CHECK_HEADERS(stdlib.h) + # AC_PREFIX_PROGRAM(wmaker) dnl Support for PIXMAPDIR option diff --git a/src/Makefile.am b/src/Makefile.am index 345fd1cb..7640382c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -95,6 +95,8 @@ wmaker_SOURCES = \ winmenu.c \ winspector.h \ winspector.c \ + wmspec.c \ + wmspec.h \ workspace.c \ workspace.h \ wsound.c \ diff --git a/src/screen.c b/src/screen.c index 27f723c9..f0330d4b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -859,12 +859,19 @@ wScreenInit(int screen_number) } + +static WArea subtractRectangle(WArea area, WArea rect) +{ + WArea result = area; + + +} + + void wScreenUpdateUsableArea(WScreen *scr) { -#ifdef GNOME_STUFF WReservedArea *area; -#endif scr->totalUsableArea = scr->usableArea; diff --git a/src/screen.h b/src/screen.h index e25f82a6..c38c2710 100644 --- a/src/screen.h +++ b/src/screen.h @@ -41,14 +41,14 @@ #define WTB_PFOCUSED 4 #define WTB_MENU 6 -#ifdef GNOME_STUFF + /* an area of the screen reserved by some window */ typedef struct WReservedArea { WArea area; Window window; struct WReservedArea *next; } WReservedArea; -#endif + typedef struct WAppIconChain { @@ -131,9 +131,7 @@ typedef struct _WScreen { int current_workspace; /* current workspace number */ -#ifdef GNOME_STUFF WReservedArea *reservedAreas; /* used to build totalUsableArea */ -#endif WArea usableArea; /* area of the workspace where * we can put windows on, as defined @@ -300,6 +298,10 @@ typedef struct _WScreen { #ifdef KWM_HINTS Window kwm_dock; #endif + +#ifdef NET_HINTS + struct NetData *netdata; +#endif int helper_fd; pid_t helper_pid; diff --git a/src/stacking.c b/src/stacking.c index b3ef5eba..38f8f501 100644 --- a/src/stacking.c +++ b/src/stacking.c @@ -572,6 +572,8 @@ RemoveFromStackList(WCoreWindow *frame) frame->stacking->under); frame->screen_ptr->window_count--; + + WMPostNotificationName(WMNResetStacking, frame->screen_ptr, NULL); } diff --git a/src/window.h b/src/window.h index 58529871..4c86dd6f 100644 --- a/src/window.h +++ b/src/window.h @@ -290,6 +290,11 @@ typedef struct WWindow { unsigned int olwm_push_pin_out:1;/* emulate pushpin behaviour */ unsigned int olwm_limit_menu:1; #endif +#ifdef NET_HINTS + unsigned int net_state_from_client:1; /* state hint was set by client */ + unsigned int net_skip_taskbar:1; + unsigned int net_skip_pager:1; +#endif } flags; /* state of the window */ struct WIcon *icon; /* icon info for the window */ diff --git a/src/wmspec.c b/src/wmspec.c new file mode 100644 index 00000000..92aaefdd --- /dev/null +++ b/src/wmspec.c @@ -0,0 +1,456 @@ +/* wmspec.c-- support for the wm-spec Hints + * + * Window Maker window manager + * + * Copyright (c) 1998, 2001 Alfredo K. Kojima + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "wconfig.h" + +#include +#include + +#include "WindowMaker.h" +#include "window.h" +#include "screen.h" +#include "framewin.h" +#include "actions.h" + + +static Atom net_supported; +static Atom net_client_list; +static Atom net_client_list_stacking; +static Atom net_number_of_desktops; +static Atom net_desktop_geometry; +static Atom net_desktop_viewport; +static Atom net_current_desktop; +static Atom net_active_window; +static Atom net_workarea; +static Atom net_supporting_wm_check; +/* net_virtual_roots N/A */ +/* TODO + * _NET_WM_NAME + * _NET_WM_VISIBLE_NAME + * _NET_WM_ICON_NAME + * _NET_WM_VISIBLE_ICON_NAME + * _NET_WM_WINDOW_TYPE + */ +static Atom net_wm_desktop; +static Atom net_wm_state; + +static Atom net_wm_strut; +/* + * _NET_WM_ICON_GEOMETRY + * _NET_WM_ICON + * _NET_WM_PID + * _NET_WM_HANDLED_ICONS + * + */ + +static Atom net_wm_state_modal; +static Atom net_wm_state_sticky; +static Atom net_wm_state_maximized_vert; +static Atom net_wm_state_maximized_horz; +static Atom net_wm_state_shaded; +static Atom net_wm_state_skip_taskbar; +static Atom net_wm_state_skip_pager; + + + +/* states */ + + +static char *atomNames[] = { + "_NET_SUPPORTED", + "_NET_CLIENT_LIST", + "_NET_NUMBER_OF_DESKTOPS", + "_NET_DESKTOP_GEOMETRY", + "_NET_DESKTOP_VIEWPORT", + "_NET_CURRENT_DESKTOP", + "_NET_ACTIVE_WINDOW", + "_NET_WORKAREA", + "_NET_SUPPORTING_WM_CHECK", + "_NET_WM_DESKTOP", + "_NET_WM_STATE", + "_NET_WM_STRUT", + + + + "_NET_WM_STATE_MODAL", + "_NET_WM_STATE_STICKY", + "_NET_WM_STATE_MAXIMIZED_VERT", + "_NET_WM_STATE_MAXIMIZED_HORZ", + "_NET_WM_STATE_SHADED", + "_NET_WM_STATE_SKIP_TASKBAR", + "_NET_WM_STATE_SKIP_PAGER" +}; + +static void observer(void *self, WMNotification *notif); +static void wsobserver(void *self, WMNotification *notif); + + +typedef struct NetData { + WScreen *scr; + Window *client_windows; + int client_count; + int client_size; +} NetData; + + + + + +static void setSupportedHints(WScreen *scr) +{ + Atom atom[32]; + int i = 0; + unsigned int sizes[2]; + + /* set supported hints list */ + + atom[i++] = net_client_list; + + + XChangeProperty(dpy, scr->root_win, + net_supported, XA_ATOM, 32, + PropModeReplace, (unsigned char*)atom, i); + + /* set supporting wm hint */ + XChangeProperty(dpy, scr->root_win, + net_supporting_wm_check, XA_WINDOW, 32, + PropModeReplace, + (unsigned char*)&scr->info_window, 1); + + XChangeProperty(dpy, scr->info_window, + net_supporting_wm_check, XA_WINDOW, 32, + PropModeReplace, + (unsigned char*)&scr->info_window, 1); + + + /* set desktop geometry. dynamic change is not supported */ + sizes[0] = scr->scr_width; + sizes[1] = scr->scr_height; + + XChangeProperty(dpy, scr->root_win, + net_desktop_geometry, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*)&sizes, 2); + + /* set desktop viewport. dynamic change is not supported */ + sizes[0] = 0; + sizes[1] = 0; + + XChangeProperty(dpy, scr->root_win, + net_desktop_viewport, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*)&sizes, 2); + +} + + +void netwmInitialize(WScreen *scr) +{ + NetData *data; + Atom atom[32]; + +#ifdef HAVE_XINTERNATOMS + XInternAtoms(dpy, atomNames, sizeof(atomNames)/sizeof(char*), + False, atom); +#else + { + int i; + for (i = 0; i < sizeof(atomNames)/sizeof(char*); i++) { + atom[i] = XInternAtom(dpy, atomNames[i], False); + } + } +#endif + net_supported = atom[0]; + net_client_list = atom[1]; + + setSupportedHints(scr); + + data = wmalloc(sizeof(NetData)); + data->scr = scr; + data->client_windows = NULL; + data->client_count = 0; + data->client_size = 0; + + WMAddNotificationObserver(observer, data, WMNManaged, NULL); + WMAddNotificationObserver(observer, data, WMNUnmanaged, NULL); + WMAddNotificationObserver(observer, data, WMNChangedWorkspace, NULL); + WMAddNotificationObserver(observer, data, WMNChangedState, NULL); + WMAddNotificationObserver(observer, data, WMNChangedFocus, NULL); + WMAddNotificationObserver(observer, data, WMNChangedStacking, NULL); + WMAddNotificationObserver(observer, data, WMNChangedName, NULL); + + WMAddNotificationObserver(wsobserver, data, WMNWorkspaceCreated, NULL); + WMAddNotificationObserver(wsobserver, data, WMNWorkspaceDestroyed, NULL); + WMAddNotificationObserver(wsobserver, data, WMNWorkspaceChanged, NULL); + WMAddNotificationObserver(wsobserver, data, WMNWorkspaceNameChanged, NULL); +} + + +void +netwmUpdateWorkarea(WScreen *scr) +{ + unsigned int area[4]; + + /* XXX */ + + XChangeProperty(dpy, scr->root_win, net_workarea, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*)area, 4); +} + + + +static void +updateClientList(WScreen *scr, WWindow *wwin, Bool added) +{ + NetData *data = scr->netdata; + + if (added) { + if (data->client_count == data->client_size) { + data->client_size += 20; + data->client_windows = wrealloc(data->client_windows, + sizeof(Window)*data->client_size); + } + + data->client_windows[data->client_count++] = wwin->client_win; + + XChangeProperty(dpy, scr->root_win, net_client_list, XA_WINDOW, 32, + PropModeAppend, (unsigned char*)&wwin->client_win, 1); + } else { + int i; + for (i = 0; i < data->client_count; i++) { + if (data->client_windows[i] == wwin->client_win) { + if (data->client_count-1 > i) { + memmove(data->client_windows+i, + data->client_windows+i+1, + (data->client_count-i-1)*sizeof(Window)); + } + data->client_count--; + break; + } + } + + /* update client list */ + XChangeProperty(dpy, scr->root_win, net_client_list, XA_WINDOW, 32, + PropModeReplace, + (unsigned char *)data->client_windows, + data->client_count); + } + XFlush(dpy); +} + + + +static void +updateClientListStacking(WScreen *scr) +{ + WWindow *wwin; + Window *client_list; + int client_count; + WCoreWindow *tmp; + WMBagIterator iter; + + /* update client list */ + + client_list = (Window*)malloc(sizeof(Window)*scr->window_count); + if (!client_list) { + wwarning(_("out of memory while updating wm hints")); + return; + } + + WM_ETARETI_BAG(scr->stacking_list, tmp, iter) { + while (tmp) { + client_list[client_count++] = tmp->window; + tmp = tmp->stacking->under; + } + } + + XChangeProperty(dpy, scr->root_win, + net_client_list_stacking, XA_WINDOW, 32, + PropModeReplace, + (unsigned char *)client_list, client_count); + + wfree(client_list); + + XFlush(dpy); +} + + + +static void +updateWorkspaceCount(WScreen *scr) /* changeable */ +{ + unsigned int count = scr->workspace_count; + + XChangeProperty(dpy, scr->root_win, + net_number_of_desktops, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*)&count, 1); +} + + +static void +updateCurrentWorkspace(WScreen *scr) /* changeable */ +{ + unsigned int count = scr->current_workspace; + + XChangeProperty(dpy, scr->root_win, + net_current_desktop, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*)&count, 1); +} + + +static void +updateWorkspaceNames(WScreen *scr, int workspace) +{ + /* XXX UTF 8 */ +} + + +static void +updateFocusHint(WScreen *scr, WWindow *wwin) /* changeable */ +{ + Window window = None; + + if (wwin) + window = wwin->client_win; + + XChangeProperty(dpy, scr->root_win, + net_active_window, XA_WINDOW, 32, + PropModeReplace, + (unsigned char*)&window, 1); +} + + +static void +updateWorkspaceHint(WWindow *wwin, Bool del) +{ + if (del) { + XDeleteProperty(dpy, wwin->client_win, net_wm_desktop); + } else { + XChangeProperty(dpy, wwin->screen_ptr->root_win, + net_wm_desktop, XA_CARDINAL, 32, + PropModeReplace, + (unsigned char*)&wwin->frame->workspace, 1); + } +} + + +static void +updateStateHint(WWindow *wwin, Bool del) /* changeable */ +{ + if (del) { + if (!wwin->flags.net_state_from_client) + XDeleteProperty(dpy, wwin->client_win, net_wm_state); + } else { + Atom state[8]; + int i = 0; + + if (wwin->flags.omnipresent) + state[i++] = net_wm_state_sticky; + if (wwin->flags.maximized & MAX_HORIZONTAL) + state[i++] = net_wm_state_maximized_horz; + if (wwin->flags.maximized & MAX_VERTICAL) + state[i++] = net_wm_state_maximized_vert; + if (wwin->flags.shaded) + state[i++] = net_wm_state_shaded; + if (WFLAGP(wwin, skip_window_list) || wwin->flags.net_skip_taskbar) + state[i++] = net_wm_state_skip_taskbar; + if (wwin->flags.net_skip_pager) + state[i++] = net_wm_state_skip_pager; + } +} + + +static void +updateStrut(WWindow *wwin, Bool adding) +{ + if (adding) { +// XGetWindowProperty(dpy, wwin->client_win, + + /* XXX add property observer */ + } else { + } +} + + +static void +observer(void *self, WMNotification *notif) +{ + WWindow *wwin = (WWindow*)WMGetNotificationObject(notif); + const char *name = WMGetNotificationName(notif); + void *data = WMGetNotificationClientData(notif); + NetData *ndata = (NetData*)self; + + + if (strcmp(name, WMNManaged) == 0 && wwin) { + updateClientList(wwin->screen_ptr, wwin, True); + + updateStrut(wwin, True); + + } else if (strcmp(name, WMNUnmanaged) == 0 && wwin) { + updateClientList(wwin->screen_ptr, wwin, False); + updateWorkspaceHint(wwin, True); + updateStateHint(wwin, True); + + updateStrut(wwin, False); + + } else if (strcmp(name, WMNResetStacking) == 0 && wwin) { + updateClientListStacking(wwin->screen_ptr); + + } else if (strcmp(name, WMNChangedStacking) == 0 && wwin) { + updateClientListStacking(wwin->screen_ptr); + + } else if (strcmp(name, WMNChangedFocus) == 0) { + updateFocusHint(ndata->scr, wwin); + + } else if (strcmp(name, WMNChangedWorkspace) == 0 && wwin) { + updateWorkspaceHint(wwin, False); + + } else if (strcmp(name, WMNChangedState) == 0 && wwin) { + updateStateHint(wwin, False); + } +} + + +static void +wsobserver(void *self, WMNotification *notif) +{ + WScreen *scr = (WScreen*)WMGetNotificationObject(notif); + const char *name = WMGetNotificationName(notif); + void *data = WMGetNotificationClientData(notif); + + if (strcmp(name, WMNWorkspaceCreated) == 0) { + updateWorkspaceCount(scr); + } else if (strcmp(name, WMNWorkspaceDestroyed) == 0) { + updateWorkspaceCount(scr); + } else if (strcmp(name, WMNWorkspaceChanged) == 0) { + updateCurrentWorkspace(scr); + } else if (strcmp(name, WMNWorkspaceNameChanged) == 0) { + updateWorkspaceNames(scr, (int)data); + } +} + + + diff --git a/src/wmspec.h b/src/wmspec.h new file mode 100644 index 00000000..1bbb8767 --- /dev/null +++ b/src/wmspec.h @@ -0,0 +1,30 @@ +/* wmspec.h-- support for the wm-spec Hints + * + * Window Maker window manager + * + * Copyright (c) 1998, 2001 Alfredo K. Kojima + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + + +#ifndef _WMSPEC_H_ +#define _WMSPEC_H_ + + + +#endif -- 2.11.4.GIT