mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 12:28:22 +01:00
*** empty log message ***
This commit is contained in:
481
src/usermenu.c
481
src/usermenu.c
@@ -62,9 +62,9 @@ extern proplist_t ReadProplistFromFile(char *file);
|
||||
extern WPreferences wPreferences;
|
||||
|
||||
typedef struct {
|
||||
WScreen *screen;
|
||||
WShortKey *key;
|
||||
int key_no;
|
||||
WScreen *screen;
|
||||
WShortKey *key;
|
||||
int key_no;
|
||||
} WUserMenuData;
|
||||
|
||||
|
||||
@@ -74,317 +74,276 @@ notifyClient(WMenu *menu, WMenuEntry *entry){
|
||||
WUserMenuData *data = entry->clientdata;
|
||||
WScreen *scr = data->screen;
|
||||
Window window;
|
||||
int i;
|
||||
int i;
|
||||
|
||||
window=scr->focused_window->client_win;
|
||||
|
||||
for(i=0;i<data->key_no;i++){
|
||||
event.xkey.type = KeyPress;
|
||||
event.xkey.display = dpy;
|
||||
event.xkey.window = window;
|
||||
event.xkey.subwindow = 0x0;
|
||||
event.xkey.x = 0x0;
|
||||
event.xkey.y = 0x0;
|
||||
event.xkey.x_root = 0x0;
|
||||
event.xkey.y_root = 0x0;
|
||||
event.xkey.keycode = data->key[i].keycode;
|
||||
event.xkey.state = data->key[i].modifier;
|
||||
event.xkey.same_screen = YES;
|
||||
XSendEvent(dpy, window, False, NoEventMask, &event);
|
||||
XFlush(dpy);
|
||||
/* should i release key too? */
|
||||
}
|
||||
for(i=0;i<data->key_no;i++){
|
||||
event.xkey.type = KeyPress;
|
||||
event.xkey.display = dpy;
|
||||
event.xkey.window = window;
|
||||
event.xkey.subwindow = 0x0;
|
||||
event.xkey.x = 0x0;
|
||||
event.xkey.y = 0x0;
|
||||
event.xkey.x_root = 0x0;
|
||||
event.xkey.y_root = 0x0;
|
||||
event.xkey.keycode = data->key[i].keycode;
|
||||
event.xkey.state = data->key[i].modifier;
|
||||
event.xkey.same_screen = YES;
|
||||
XSendEvent(dpy, window, False, NoEventMask, &event);
|
||||
XFlush(dpy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
removeUserMenudata(void *menudata){
|
||||
WUserMenuData *data = menudata;
|
||||
free(data->key);
|
||||
free(data);
|
||||
WUserMenuData *data = menudata;
|
||||
if(data->key) free(data->key);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static WUserMenuData*
|
||||
convertShortcut(WScreen *scr, proplist_t shortcut){
|
||||
WUserMenuData *data;
|
||||
KeySym ksym;
|
||||
char *k;
|
||||
char buf[128], *b;
|
||||
|
||||
data = malloc(sizeof(WUserMenuData));
|
||||
data->key = malloc(sizeof(WUserMenuData));
|
||||
data->key[0].modifier = 0;
|
||||
|
||||
strcpy(buf, PLGetString(shortcut));
|
||||
b = (char*)buf;
|
||||
|
||||
/* get modifiers */
|
||||
while ((k = strchr(b, '+'))!=NULL) {
|
||||
int mod;
|
||||
|
||||
*k = 0;
|
||||
mod = wXModifierFromKey(b);
|
||||
if (mod<0) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
data->key[0].modifier |= mod;
|
||||
|
||||
b = k+1;
|
||||
}
|
||||
|
||||
/* get key */
|
||||
ksym = XStringToKeysym(b);
|
||||
|
||||
if (ksym==NoSymbol) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->key[0].keycode = XKeysymToKeycode(dpy, ksym);
|
||||
if (data->key[0].keycode==0) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
data->screen = scr;
|
||||
data->key_no = 1;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static WUserMenuData*
|
||||
convertShortcuts(WScreen *scr, proplist_t shortcut){
|
||||
WUserMenuData *data;
|
||||
KeySym ksym;
|
||||
char *k;
|
||||
char *buffer;
|
||||
char buf[128], *b;
|
||||
int keycount,i,j,mod;
|
||||
|
||||
if (PLIsString(shortcut)){
|
||||
keycount = 1;
|
||||
}
|
||||
else if (PLIsArray(shortcut)){
|
||||
keycount = PLGetNumberOfElements(shortcut);
|
||||
}
|
||||
else return NULL;
|
||||
/*for (i=0;i<keycount;i++){*/
|
||||
|
||||
data = malloc(sizeof(WUserMenuData));
|
||||
data->key = malloc(sizeof(WShortKey)*keycount);
|
||||
|
||||
for (i=0,j=0;i<keycount;i++) {
|
||||
data->key[j].modifier = 0;
|
||||
if (PLIsArray(shortcut)) {
|
||||
strcpy(buf, PLGetString(PLGetArrayElement(shortcut, i)));
|
||||
}
|
||||
else {
|
||||
strcpy(buf, PLGetString(shortcut));
|
||||
}
|
||||
b = (char*)buf;
|
||||
WUserMenuData *data;
|
||||
KeySym ksym;
|
||||
char *k;
|
||||
char *buffer;
|
||||
char buf[128], *b;
|
||||
int keycount,i,j,mod;
|
||||
|
||||
while ((k = strchr(b, '+'))!=NULL) {
|
||||
*k = 0;
|
||||
mod = wXModifierFromKey(b);
|
||||
if (mod<0) {
|
||||
break;
|
||||
}
|
||||
data->key[j].modifier |= mod;
|
||||
b = k+1;
|
||||
}
|
||||
if (mod<0) {
|
||||
continue;
|
||||
}
|
||||
if (PLIsString(shortcut)){
|
||||
keycount = 1;
|
||||
}
|
||||
else if (PLIsArray(shortcut)){
|
||||
keycount = PLGetNumberOfElements(shortcut);
|
||||
}
|
||||
else return NULL;
|
||||
/*for (i=0;i<keycount;i++){*/
|
||||
|
||||
ksym = XStringToKeysym(b);
|
||||
if (ksym==NoSymbol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data->key[j].keycode = XKeysymToKeycode(dpy, ksym);
|
||||
if (data->key[j].keycode) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
data = wmalloc(sizeof(WUserMenuData));
|
||||
if (!data) return NULL;
|
||||
data->key = wmalloc(sizeof(WShortKey)*keycount);
|
||||
if (!data->key) {
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
for (i=0,j=0;i<keycount;i++) {
|
||||
data->key[j].modifier = 0;
|
||||
if (PLIsArray(shortcut)) {
|
||||
strcpy(buf, PLGetString(PLGetArrayElement(shortcut, i)));
|
||||
}
|
||||
else {
|
||||
strcpy(buf, PLGetString(shortcut));
|
||||
}
|
||||
b = (char*)buf;
|
||||
|
||||
while ((k = strchr(b, '+'))!=NULL) {
|
||||
*k = 0;
|
||||
mod = wXModifierFromKey(b);
|
||||
if (mod<0) {
|
||||
break;
|
||||
}
|
||||
data->key[j].modifier |= mod;
|
||||
b = k+1;
|
||||
}
|
||||
|
||||
ksym = XStringToKeysym(b);
|
||||
if (ksym==NoSymbol) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data->key[j].keycode = XKeysymToKeycode(dpy, ksym);
|
||||
if (data->key[j].keycode) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
keyover:
|
||||
|
||||
/* get key */
|
||||
if (!j) {
|
||||
free(data->key);
|
||||
free(data);
|
||||
}
|
||||
data->key_no = j;
|
||||
data->screen = scr;
|
||||
|
||||
return data;
|
||||
if (!j) {
|
||||
puts("fatal j");
|
||||
free(data->key);
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
data->key_no = j;
|
||||
data->screen = scr;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static WMenu*
|
||||
configureUserMenu(WScreen *scr, proplist_t plum){
|
||||
char *mtitle;
|
||||
WMenu *menu=NULL;
|
||||
proplist_t elem, title, command, params;
|
||||
int count,i;
|
||||
char *mtitle;
|
||||
WMenu *menu=NULL;
|
||||
proplist_t elem, title, command, params;
|
||||
int count,i;
|
||||
WUserMenuData *data;
|
||||
|
||||
if (!plum) return NULL;
|
||||
else if (!PLIsArray(plum)){
|
||||
PLRelease(plum);
|
||||
return NULL;
|
||||
}
|
||||
if (!plum) return NULL;
|
||||
if (!PLIsArray(plum)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = PLGetNumberOfElements(plum);
|
||||
if (!count) return NULL;
|
||||
count = PLGetNumberOfElements(plum);
|
||||
if (!count) return NULL;
|
||||
|
||||
elem = PLGetArrayElement(plum, 0);
|
||||
if (!PLIsString(elem)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mtitle = PLGetString(elem);
|
||||
|
||||
menu=wMenuCreateForApp(scr, mtitle, True);
|
||||
|
||||
for(i=1; i<count; i++){
|
||||
elem = PLGetArrayElement(plum,i);
|
||||
if(PLIsArray(PLGetArrayElement(elem,1))){
|
||||
WMenu *submenu;
|
||||
WMenuEntry *mentry;
|
||||
|
||||
submenu = configureUserMenu(scr,elem);
|
||||
if (submenu)
|
||||
mentry = wMenuAddCallback(menu, submenu->frame->title,NULL,NULL);
|
||||
wMenuEntrySetCascade(menu, mentry, submenu);
|
||||
}
|
||||
else {
|
||||
int idx = 0;
|
||||
proplist_t instances=0;
|
||||
elem = PLGetArrayElement(plum, 0);
|
||||
if (!PLIsString(elem)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mtitle = PLGetString(elem);
|
||||
|
||||
menu=wMenuCreateForApp(scr, mtitle, True);
|
||||
|
||||
for(i=1; i<count; i++){
|
||||
elem = PLGetArrayElement(plum,i);
|
||||
if(PLIsArray(PLGetArrayElement(elem,1))){
|
||||
WMenu *submenu;
|
||||
WMenuEntry *mentry;
|
||||
|
||||
submenu = configureUserMenu(scr,elem);
|
||||
if (submenu)
|
||||
mentry = wMenuAddCallback(menu, submenu->frame->title,
|
||||
NULL, NULL);
|
||||
wMenuEntrySetCascade(menu, mentry, submenu);
|
||||
}
|
||||
else {
|
||||
int idx = 0;
|
||||
proplist_t instances=0;
|
||||
|
||||
title = PLGetArrayElement(elem,idx++);
|
||||
command = PLGetArrayElement(elem,idx++);
|
||||
if (PLGetNumberOfElements(elem) >= 3)
|
||||
params = PLGetArrayElement(elem,idx++);
|
||||
|
||||
if (!title || !command)
|
||||
return menu;
|
||||
title = PLGetArrayElement(elem,idx++);
|
||||
command = PLGetArrayElement(elem,idx++);
|
||||
if (PLGetNumberOfElements(elem) >= 3)
|
||||
params = PLGetArrayElement(elem,idx++);
|
||||
|
||||
if (!title || !command)
|
||||
return menu;
|
||||
|
||||
if (!strcmp("SHORTCUT",PLGetString(command))){
|
||||
WMenuEntry *entry;
|
||||
data = convertShortcuts(scr, params);
|
||||
if (data){
|
||||
entry = wMenuAddCallback(menu, PLGetString(title),
|
||||
notifyClient, data);
|
||||
if (PLIsString(params)) {
|
||||
entry->rtext = GetShortcutString(PLGetString(params));
|
||||
}
|
||||
if (entry) {
|
||||
entry->free_cdata = removeUserMenudata;
|
||||
if (!strcmp("SHORTCUT",PLGetString(command))){
|
||||
WMenuEntry *entry;
|
||||
|
||||
if (PLGetNumberOfElements(elem) >= 4){
|
||||
instances = PLGetArrayElement(elem,idx++);
|
||||
if(PLIsArray(instances))
|
||||
if (instances && PLGetNumberOfElements(instances)
|
||||
&& PLIsArray(instances)){
|
||||
entry->instances = PLRetain(instances);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* else if */
|
||||
data = convertShortcuts(scr, params);
|
||||
if (data){
|
||||
entry = wMenuAddCallback(menu, PLGetString(title),
|
||||
notifyClient, data);
|
||||
|
||||
}
|
||||
}
|
||||
return menu;
|
||||
if (entry) {
|
||||
if (PLIsString(params)) {
|
||||
entry->rtext = GetShortcutString(PLGetString(params));
|
||||
}
|
||||
entry->free_cdata = removeUserMenudata;
|
||||
|
||||
if (PLGetNumberOfElements(elem) >= 4){
|
||||
instances = PLGetArrayElement(elem,idx++);
|
||||
if(PLIsArray(instances))
|
||||
if (instances && PLGetNumberOfElements(instances)
|
||||
&& PLIsArray(instances)){
|
||||
entry->instances = PLRetain(instances);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
void
|
||||
wUserMenuRefreshInstances(WMenu *menu, WWindow *wwin)
|
||||
{
|
||||
WMenuEntry* entry;
|
||||
int i,j,count,paintflag;
|
||||
|
||||
paintflag=0;
|
||||
|
||||
if(!menu) return;
|
||||
WMenuEntry* entry;
|
||||
int i,j,count,paintflag;
|
||||
|
||||
paintflag=0;
|
||||
|
||||
if(!menu) return;
|
||||
|
||||
for (i=0; i<menu->entry_no; i++) {
|
||||
if (menu->entries[i]->instances){
|
||||
proplist_t ins;
|
||||
int oldflag;
|
||||
count = PLGetNumberOfElements(menu->entries[i]->instances);
|
||||
for (i=0; i<menu->entry_no; i++) {
|
||||
if (menu->entries[i]->instances){
|
||||
proplist_t ins;
|
||||
int oldflag;
|
||||
count = PLGetNumberOfElements(menu->entries[i]->instances);
|
||||
|
||||
oldflag = menu->entries[i]->flags.enabled;
|
||||
menu->entries[i]->flags.enabled = 0;
|
||||
for (j=0; j<count;j++){
|
||||
ins = PLGetArrayElement(menu->entries[i]->instances,j);
|
||||
if (!strcmp(wwin->wm_instance,PLGetString(ins))){
|
||||
menu->entries[i]->flags.enabled = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oldflag != menu->entries[i]->flags.enabled)
|
||||
paintflag=1;
|
||||
}
|
||||
}
|
||||
for (i=0; i < menu->cascade_no; i++) {
|
||||
if (!menu->cascades[i]->flags.brother)
|
||||
wUserMenuRefreshInstances(menu->cascades[i], wwin);
|
||||
else
|
||||
wUserMenuRefreshInstances(menu->cascades[i]->brother, wwin);
|
||||
}
|
||||
oldflag = menu->entries[i]->flags.enabled;
|
||||
menu->entries[i]->flags.enabled = 0;
|
||||
for (j=0; j<count;j++){
|
||||
ins = PLGetArrayElement(menu->entries[i]->instances,j);
|
||||
if (!strcmp(wwin->wm_instance,PLGetString(ins))){
|
||||
menu->entries[i]->flags.enabled = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oldflag != menu->entries[i]->flags.enabled)
|
||||
paintflag=1;
|
||||
}
|
||||
}
|
||||
for (i=0; i < menu->cascade_no; i++) {
|
||||
if (!menu->cascades[i]->flags.brother)
|
||||
wUserMenuRefreshInstances(menu->cascades[i], wwin);
|
||||
else
|
||||
wUserMenuRefreshInstances(menu->cascades[i]->brother, wwin);
|
||||
}
|
||||
|
||||
if(paintflag)
|
||||
wMenuPaint(menu);
|
||||
if(paintflag)
|
||||
wMenuPaint(menu);
|
||||
}
|
||||
|
||||
|
||||
static WMenu*
|
||||
readUserMenuFile(WScreen *scr, char *file_name)
|
||||
{
|
||||
WMenu *menu=NULL;
|
||||
char *mtitle;
|
||||
|
||||
proplist_t plum, elem, title, command, params;
|
||||
|
||||
int count,i;
|
||||
WMenu *menu;
|
||||
char *mtitle;
|
||||
proplist_t plum, elem, title, command, params;
|
||||
int count,i;
|
||||
|
||||
plum = ReadProplistFromFile(file_name);
|
||||
/**/
|
||||
|
||||
if(plum){
|
||||
menu = configureUserMenu(scr, plum);
|
||||
PLRelease(plum);
|
||||
}
|
||||
menu=NULL;
|
||||
plum = ReadProplistFromFile(file_name);
|
||||
/**/
|
||||
|
||||
if(plum){
|
||||
menu = configureUserMenu(scr, plum);
|
||||
PLRelease(plum);
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
WMenu*
|
||||
wUserMenuGet(WScreen *scr, WWindow *wwin){
|
||||
WMenu *menu = NULL;
|
||||
char buffer[100];
|
||||
char *prefix, *menufile;
|
||||
WMenu *menu = NULL;
|
||||
char buffer[100];
|
||||
char *prefix, *menufile;
|
||||
|
||||
prefix = getenv("HOME");
|
||||
if (!prefix)
|
||||
prefix = ".";
|
||||
menufile = malloc(strlen(prefix)+64);
|
||||
if (!menufile) return NULL;
|
||||
|
||||
if (wwin) {
|
||||
FILE *f;
|
||||
sprintf(menufile, "%s/%s.%s.menu",
|
||||
prefix, wwin->wm_instance, wwin->wm_class);
|
||||
f = fopen(menufile, "r");
|
||||
if (f) {
|
||||
fclose(f);
|
||||
menu = readUserMenuFile(scr, menufile);
|
||||
}
|
||||
}
|
||||
prefix = getenv("HOME");
|
||||
if (!prefix)
|
||||
prefix = ".";
|
||||
/* this file/path code will be replaced :D - ]d */
|
||||
menufile = malloc(strlen(prefix)+128);
|
||||
if (!menufile) return NULL;
|
||||
|
||||
if (wwin) {
|
||||
FILE *f;
|
||||
sprintf(menufile, "%s/GNUstep/Library/WindowMaker/UserMenus/%s.%s.menu",
|
||||
prefix, wwin->wm_instance, wwin->wm_class);
|
||||
f = fopen(menufile, "r");
|
||||
if (f) {
|
||||
fclose(f);
|
||||
menu = readUserMenuFile(scr, menufile);
|
||||
}
|
||||
}
|
||||
|
||||
free(menufile);
|
||||
return menu;
|
||||
free(menufile);
|
||||
return menu;
|
||||
}
|
||||
|
||||
#endif /* USER_MENU */
|
||||
|
||||
Reference in New Issue
Block a user