sync with bb-cvs (fixes the java bug, plus menu prasing redone)
This commit is contained in:
parent
9e7f5d2208
commit
03f9d6170b
2 changed files with 381 additions and 450 deletions
655
src/Screen.cc
655
src/Screen.cc
|
@ -1646,37 +1646,38 @@ void BScreen::InitMenu(void) {
|
|||
memset(label, 0, 1024);
|
||||
|
||||
while (fgets(line, 1024, menu_file) && ! feof(menu_file)) {
|
||||
if (line[0] != '#') {
|
||||
int i, key = 0, index = -1, len = strlen(line);
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (line[i] == '[') index = 0;
|
||||
else if (line[i] == ']') break;
|
||||
else if (line[i] != ' ')
|
||||
if (index++ >= 0)
|
||||
key += tolower(line[i]);
|
||||
}
|
||||
int i, key = 0, index = -1, len = strlen(line);
|
||||
|
||||
if (key == 517) { // [begin]
|
||||
index = -1;
|
||||
for (i = index; i < len; i++) {
|
||||
if (line[i] == '(') index = 0;
|
||||
else if (line[i] == ')') break;
|
||||
else if (index++ >= 0) {
|
||||
if (line[i] == '\\' && i < len - 1) i++;
|
||||
label[index - 1] = line[i];
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
if (line[i] == '[') index = 0;
|
||||
else if (line[i] == ']') break;
|
||||
else if (line[i] != ' ')
|
||||
if (index++ >= 0)
|
||||
key += tolower(line[i]);
|
||||
}
|
||||
|
||||
if (key == 517) { // [begin]
|
||||
index = -1;
|
||||
for (i = index; i < len; i++) {
|
||||
if (line[i] == '(') index = 0;
|
||||
else if (line[i] == ')') break;
|
||||
else if (index++ >= 0) {
|
||||
if (line[i] == '\\' && i < len - 1) i++;
|
||||
label[index - 1] = line[i];
|
||||
}
|
||||
|
||||
if (index == -1) index = 0;
|
||||
label[index] = '\0';
|
||||
|
||||
rootmenu->setLabel(label);
|
||||
defaultMenu = parseMenuFile(menu_file, rootmenu);
|
||||
if (! defaultMenu)
|
||||
blackbox->addMenuTimestamp(menu_filename);
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == -1) index = 0;
|
||||
label[index] = '\0';
|
||||
|
||||
rootmenu->setLabel(label);
|
||||
defaultMenu = parseMenuFile(menu_file, rootmenu);
|
||||
if (! defaultMenu)
|
||||
blackbox->addMenuTimestamp(menu_filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1698,321 +1699,313 @@ void BScreen::InitMenu(void) {
|
|||
}
|
||||
|
||||
|
||||
bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
|
||||
char line[1024], label[1024], command[1024];
|
||||
static
|
||||
void string_within(char begin, char end, const char *input, size_t length,
|
||||
char *output) {
|
||||
bool parse = False;
|
||||
size_t index = 0;
|
||||
|
||||
while (! feof(file)) {
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (input[i] == begin) {
|
||||
parse = True;
|
||||
} else if (input[i] == end) {
|
||||
break;
|
||||
} else if (parse) {
|
||||
if (input[i] == '\\' && i < length - 1) i++;
|
||||
output[index++] = input[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (parse)
|
||||
output[index] = '\0';
|
||||
else
|
||||
output[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
bool BScreen::parseMenuFile(FILE *file, Rootmenu *menu) {
|
||||
char line[1024], keyword[1024], label[1024], command[1024];
|
||||
bool done = False;
|
||||
|
||||
while (! (done || feof(file))) {
|
||||
memset(line, 0, 1024);
|
||||
memset(label, 0, 1024);
|
||||
memset(command, 0, 1024);
|
||||
|
||||
if (fgets(line, 1024, file)) {
|
||||
if (line[0] != '#') {
|
||||
int i, key = 0, parse = 0, index = -1, line_length = strlen(line);
|
||||
if (! fgets(line, 1024, file))
|
||||
continue;
|
||||
|
||||
// determine the keyword
|
||||
for (i = 0; i < line_length; i++) {
|
||||
if (line[i] == '[') parse = 1;
|
||||
else if (line[i] == ']') break;
|
||||
else if (line[i] != ' ')
|
||||
if (parse)
|
||||
key += tolower(line[i]);
|
||||
}
|
||||
if (line[0] == '#') // comment, skip it
|
||||
continue;
|
||||
|
||||
// get the label enclosed in ()'s
|
||||
parse = 0;
|
||||
size_t line_length = strlen(line);
|
||||
unsigned int key = 0;
|
||||
|
||||
for (i = 0; i < line_length; i++) {
|
||||
if (line[i] == '(') {
|
||||
index = 0;
|
||||
parse = 1;
|
||||
} else if (line[i] == ')') break;
|
||||
else if (index++ >= 0) {
|
||||
if (line[i] == '\\' && i < line_length - 1) i++;
|
||||
label[index - 1] = line[i];
|
||||
}
|
||||
}
|
||||
// get the keyword enclosed in []'s
|
||||
string_within('[', ']', line, line_length, keyword);
|
||||
|
||||
if (parse) {
|
||||
label[index] = '\0';
|
||||
} else {
|
||||
label[0] = '\0';
|
||||
}
|
||||
|
||||
// get the command enclosed in {}'s
|
||||
parse = 0;
|
||||
index = -1;
|
||||
for (i = 0; i < line_length; i++) {
|
||||
if (line[i] == '{') {
|
||||
index = 0;
|
||||
parse = 1;
|
||||
} else if (line[i] == '}') break;
|
||||
else if (index++ >= 0) {
|
||||
if (line[i] == '\\' && i < line_length - 1) i++;
|
||||
command[index - 1] = line[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (parse) {
|
||||
command[index] = '\0';
|
||||
} else {
|
||||
command[0] = '\0';
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 311: // end
|
||||
return ((menu->getCount() == 0) ? True : False);
|
||||
|
||||
break;
|
||||
|
||||
case 333: // nop
|
||||
if (! *label)
|
||||
label[0] = '\0';
|
||||
menu->insert(label);
|
||||
|
||||
break;
|
||||
|
||||
case 421: // exec
|
||||
if (! (*label && *command)) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenEXECError,
|
||||
"BScreen::parseMenuFile: [exec] error, "
|
||||
"no menu label and/or command defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, BScreen::Execute, command);
|
||||
|
||||
break;
|
||||
|
||||
case 442: // exit
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenEXITError,
|
||||
"BScreen::parseMenuFile: [exit] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, BScreen::Exit);
|
||||
|
||||
break;
|
||||
|
||||
case 561: { // style
|
||||
if (! (*label && *command)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLEError,
|
||||
"BScreen::parseMenuFile: [style] error, "
|
||||
"no menu label and/or filename defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
string style = expandTilde(command);
|
||||
|
||||
menu->insert(label, BScreen::SetStyle, style.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case 630: // config
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenCONFIGError,
|
||||
"BScreen::parseMenufile: [config] error, "
|
||||
"no label defined"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, configmenu);
|
||||
|
||||
break;
|
||||
|
||||
case 740: // include
|
||||
{
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenINCLUDEError,
|
||||
"BScreen::parseMenuFile: [include] error, "
|
||||
"no filename defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
string newfile = expandTilde(label);
|
||||
FILE *submenufile = fopen(newfile.c_str(), "r");
|
||||
|
||||
if (submenufile) {
|
||||
struct stat buf;
|
||||
if (fstat(fileno(submenufile), &buf) ||
|
||||
! S_ISREG(buf.st_mode)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenINCLUDEErrorReg,
|
||||
"BScreen::parseMenuFile: [include] error: "
|
||||
"'%s' is not a regular file\n"), newfile.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (! feof(submenufile)) {
|
||||
if (! parseMenuFile(submenufile, menu))
|
||||
blackbox->addMenuTimestamp(newfile);
|
||||
|
||||
fclose(submenufile);
|
||||
}
|
||||
} else {
|
||||
perror(newfile.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 767: // submenu
|
||||
{
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenSUBMENUError,
|
||||
"BScreen::parseMenuFile: [submenu] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
Rootmenu *submenu = new Rootmenu(this);
|
||||
|
||||
if (*command)
|
||||
submenu->setLabel(command);
|
||||
else
|
||||
submenu->setLabel(label);
|
||||
|
||||
parseMenuFile(file, submenu);
|
||||
submenu->update();
|
||||
menu->insert(label, submenu);
|
||||
rootmenuList.push_back(submenu);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 773: // restart
|
||||
{
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenRESTARTError,
|
||||
"BScreen::parseMenuFile: [restart] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*command)
|
||||
menu->insert(label, BScreen::RestartOther, command);
|
||||
else
|
||||
menu->insert(label, BScreen::Restart);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 845: // reconfig
|
||||
{
|
||||
if (! *label) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenRECONFIGError,
|
||||
"BScreen::parseMenuFile: [reconfig] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, BScreen::Reconfigure);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 995: // stylesdir
|
||||
case 1113: // stylesmenu
|
||||
{
|
||||
bool newmenu = ((key == 1113) ? True : False);
|
||||
|
||||
if (! *label || (! *command && newmenu)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLESDIRError,
|
||||
"BScreen::parseMenuFile: [stylesdir/stylesmenu]"
|
||||
" error, no directory defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
char *directory = ((newmenu) ? command : label);
|
||||
|
||||
string stylesdir = expandTilde(directory);
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
if (! stat(stylesdir.c_str(), &statbuf)) {
|
||||
if (S_ISDIR(statbuf.st_mode)) {
|
||||
Rootmenu *stylesmenu;
|
||||
|
||||
if (newmenu)
|
||||
stylesmenu = new Rootmenu(this);
|
||||
else
|
||||
stylesmenu = menu;
|
||||
|
||||
DIR *d = opendir(stylesdir.c_str());
|
||||
struct dirent *p;
|
||||
std::vector<string> ls;
|
||||
|
||||
while((p = readdir(d)))
|
||||
ls.push_back(p->d_name);
|
||||
|
||||
closedir(d);
|
||||
|
||||
std::sort(ls.begin(), ls.end());
|
||||
|
||||
std::vector<string>::iterator it = ls.begin(),
|
||||
end = ls.end();
|
||||
for (; it != end; ++it) {
|
||||
const string& fname = *it;
|
||||
|
||||
if (fname[fname.size()-1] == '~')
|
||||
continue;
|
||||
|
||||
string style = stylesdir;
|
||||
style += '/';
|
||||
style += fname;
|
||||
|
||||
if (! stat(style.c_str(), &statbuf) &&
|
||||
S_ISREG(statbuf.st_mode))
|
||||
stylesmenu->insert(fname, BScreen::SetStyle, style);
|
||||
}
|
||||
|
||||
stylesmenu->update();
|
||||
|
||||
if (newmenu) {
|
||||
stylesmenu->setLabel(label);
|
||||
menu->insert(label, stylesmenu);
|
||||
rootmenuList.push_back(stylesmenu);
|
||||
}
|
||||
|
||||
blackbox->addMenuTimestamp(stylesdir);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLESDIRErrorNotDir,
|
||||
"BScreen::parseMenuFile:"
|
||||
" [stylesdir/stylesmenu] error, %s is not a"
|
||||
" directory\n"), stylesdir.c_str());
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLESDIRErrorNoExist,
|
||||
"BScreen::parseMenuFile: [stylesdir/stylesmenu]"
|
||||
" error, %s does not exist\n"), stylesdir.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1090: // workspaces
|
||||
{
|
||||
if (! *label) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenWORKSPACESError,
|
||||
"BScreen:parseMenuFile: [workspaces] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, workspacemenu);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (keyword[0] == '\0') { // no keyword, no menu entry
|
||||
continue;
|
||||
} else {
|
||||
size_t len = strlen(keyword);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
if (keyword[i] != ' ')
|
||||
key += tolower(keyword[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// get the label enclosed in ()'s
|
||||
string_within('(', ')', line, line_length, label);
|
||||
|
||||
// get the command enclosed in {}'s
|
||||
string_within('{', '}', line, line_length, command);
|
||||
|
||||
switch (key) {
|
||||
case 311: // end
|
||||
done = True;
|
||||
|
||||
break;
|
||||
|
||||
case 333: // nop
|
||||
if (! *label)
|
||||
label[0] = '\0';
|
||||
menu->insert(label);
|
||||
|
||||
break;
|
||||
|
||||
case 421: // exec
|
||||
if (! (*label && *command)) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenEXECError,
|
||||
"BScreen::parseMenuFile: [exec] error, "
|
||||
"no menu label and/or command defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, BScreen::Execute, command);
|
||||
|
||||
break;
|
||||
|
||||
case 442: // exit
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenEXITError,
|
||||
"BScreen::parseMenuFile: [exit] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, BScreen::Exit);
|
||||
|
||||
break;
|
||||
|
||||
case 561: { // style
|
||||
if (! (*label && *command)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLEError,
|
||||
"BScreen::parseMenuFile: [style] error, "
|
||||
"no menu label and/or filename defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
string style = expandTilde(command);
|
||||
|
||||
menu->insert(label, BScreen::SetStyle, style.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case 630: // config
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenCONFIGError,
|
||||
"BScreen::parseMenufile: [config] error, "
|
||||
"no label defined"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, configmenu);
|
||||
|
||||
break;
|
||||
|
||||
case 740: { // include
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenINCLUDEError,
|
||||
"BScreen::parseMenuFile: [include] error, "
|
||||
"no filename defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
string newfile = expandTilde(label);
|
||||
FILE *submenufile = fopen(newfile.c_str(), "r");
|
||||
|
||||
if (! submenufile) {
|
||||
perror(newfile.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
struct stat buf;
|
||||
if (fstat(fileno(submenufile), &buf) ||
|
||||
! S_ISREG(buf.st_mode)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenINCLUDEErrorReg,
|
||||
"BScreen::parseMenuFile: [include] error: "
|
||||
"'%s' is not a regular file\n"), newfile.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (! feof(submenufile)) {
|
||||
if (! parseMenuFile(submenufile, menu))
|
||||
blackbox->addMenuTimestamp(newfile);
|
||||
|
||||
fclose(submenufile);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 767: { // submenu
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenSUBMENUError,
|
||||
"BScreen::parseMenuFile: [submenu] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
Rootmenu *submenu = new Rootmenu(this);
|
||||
|
||||
if (*command)
|
||||
submenu->setLabel(command);
|
||||
else
|
||||
submenu->setLabel(label);
|
||||
|
||||
parseMenuFile(file, submenu);
|
||||
submenu->update();
|
||||
menu->insert(label, submenu);
|
||||
rootmenuList.push_back(submenu);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 773: { // restart
|
||||
if (! *label) {
|
||||
fprintf(stderr, i18n(ScreenSet, ScreenRESTARTError,
|
||||
"BScreen::parseMenuFile: [restart] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*command)
|
||||
menu->insert(label, BScreen::RestartOther, command);
|
||||
else
|
||||
menu->insert(label, BScreen::Restart);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 845: { // reconfig
|
||||
if (! *label) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenRECONFIGError,
|
||||
"BScreen::parseMenuFile: [reconfig] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, BScreen::Reconfigure);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 995: // stylesdir
|
||||
case 1113: { // stylesmenu
|
||||
bool newmenu = ((key == 1113) ? True : False);
|
||||
|
||||
if (! *label || (! *command && newmenu)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLESDIRError,
|
||||
"BScreen::parseMenuFile: [stylesdir/stylesmenu]"
|
||||
" error, no directory defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
char *directory = ((newmenu) ? command : label);
|
||||
|
||||
string stylesdir = expandTilde(directory);
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(stylesdir.c_str(), &statbuf) == -1) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLESDIRErrorNoExist,
|
||||
"BScreen::parseMenuFile: [stylesdir/stylesmenu]"
|
||||
" error, %s does not exist\n"), stylesdir.c_str());
|
||||
continue;
|
||||
}
|
||||
if (! S_ISDIR(statbuf.st_mode)) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenSTYLESDIRErrorNotDir,
|
||||
"BScreen::parseMenuFile:"
|
||||
" [stylesdir/stylesmenu] error, %s is not a"
|
||||
" directory\n"), stylesdir.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
Rootmenu *stylesmenu;
|
||||
|
||||
if (newmenu)
|
||||
stylesmenu = new Rootmenu(this);
|
||||
else
|
||||
stylesmenu = menu;
|
||||
|
||||
DIR *d = opendir(stylesdir.c_str());
|
||||
struct dirent *p;
|
||||
std::vector<string> ls;
|
||||
|
||||
while((p = readdir(d)))
|
||||
ls.push_back(p->d_name);
|
||||
|
||||
closedir(d);
|
||||
|
||||
std::sort(ls.begin(), ls.end());
|
||||
|
||||
std::vector<string>::iterator it = ls.begin(),
|
||||
end = ls.end();
|
||||
for (; it != end; ++it) {
|
||||
const string& fname = *it;
|
||||
|
||||
if (fname[fname.size()-1] == '~')
|
||||
continue;
|
||||
|
||||
string style = stylesdir;
|
||||
style += '/';
|
||||
style += fname;
|
||||
|
||||
if (! stat(style.c_str(), &statbuf) && S_ISREG(statbuf.st_mode))
|
||||
stylesmenu->insert(fname, BScreen::SetStyle, style);
|
||||
}
|
||||
|
||||
stylesmenu->update();
|
||||
|
||||
if (newmenu) {
|
||||
stylesmenu->setLabel(label);
|
||||
menu->insert(label, stylesmenu);
|
||||
rootmenuList.push_back(stylesmenu);
|
||||
}
|
||||
|
||||
blackbox->addMenuTimestamp(stylesdir);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1090: { // workspaces
|
||||
if (! *label) {
|
||||
fprintf(stderr,
|
||||
i18n(ScreenSet, ScreenWORKSPACESError,
|
||||
"BScreen:parseMenuFile: [workspaces] error, "
|
||||
"no menu label defined\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
menu->insert(label, workspacemenu);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ((menu->getCount() == 0) ? True : False);
|
||||
|
|
176
src/Window.cc
176
src/Window.cc
|
@ -107,11 +107,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: initial (%d, %d) w: %d, h: %d\n", client.window,
|
||||
wattrib.x, wattrib.y, wattrib.width, wattrib.height);
|
||||
#endif // DEBUG
|
||||
|
||||
// set the eventmask early in the game so that we make sure we get
|
||||
// all the events we are interested in
|
||||
XSetWindowAttributes attrib_set;
|
||||
|
@ -167,36 +162,31 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
client.rect.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
|
||||
client.old_bw = wattrib.border_width;
|
||||
|
||||
windowmenu = 0;
|
||||
lastButtonPressTime = 0;
|
||||
|
||||
timer = new BTimer(blackbox, this);
|
||||
timer->setTimeout(blackbox->getAutoRaiseDelay());
|
||||
|
||||
windowmenu = new Windowmenu(this);
|
||||
|
||||
// get size, aspect, minimum/maximum size and other hints set by the
|
||||
// client
|
||||
|
||||
if (! getBlackboxHints()) {
|
||||
getMWMHints();
|
||||
getNetWMHints();
|
||||
}
|
||||
|
||||
// get size, aspect, minimum/maximum size and other hints set by the
|
||||
// client
|
||||
getWMProtocols();
|
||||
getWMHints();
|
||||
getWMNormalHints();
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: after hints (%d, %d) w: %d, h: %d\n", client.window,
|
||||
client.rect.x(), client.rect.y(),
|
||||
client.rect.width(), client.rect.height());
|
||||
#endif // DEBUG
|
||||
|
||||
frame.window = createToplevelWindow();
|
||||
frame.plate = createChildWindow(frame.window);
|
||||
associateClientWindow();
|
||||
|
||||
blackbox->saveWindowSearch(frame.window, this);
|
||||
|
||||
frame.plate = createChildWindow(frame.window);
|
||||
blackbox->saveWindowSearch(frame.plate, this);
|
||||
blackbox->saveWindowSearch(client.window, this);
|
||||
|
||||
// determine if this is a transient window
|
||||
getTransientInfo();
|
||||
|
@ -206,6 +196,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
getWindowType();
|
||||
|
||||
// adjust the window decorations/behavior based on the window type
|
||||
|
||||
switch (window_type) {
|
||||
case Type_Desktop:
|
||||
case Type_Dock:
|
||||
|
@ -231,6 +222,8 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
break;
|
||||
}
|
||||
|
||||
setAllowedActions();
|
||||
|
||||
// further adjeust the window's decorations/behavior based on window sizes
|
||||
if ((client.normal_hint_flags & PMinSize) &&
|
||||
(client.normal_hint_flags & PMaxSize) &&
|
||||
|
@ -239,18 +232,17 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
decorations &= ~(Decor_Maximize | Decor_Handle);
|
||||
functions &= ~(Func_Resize | Func_Maximize);
|
||||
}
|
||||
|
||||
if (decorations & Decor_Titlebar)
|
||||
createTitlebar();
|
||||
|
||||
if (decorations & Decor_Handle)
|
||||
createHandle();
|
||||
|
||||
// apply the size and gravity hint to the frame
|
||||
|
||||
upsize();
|
||||
|
||||
#ifdef DFEBUG
|
||||
fprintf(stderr, "0x%lx: sizes reflect the frame from now on\n",
|
||||
client.window);
|
||||
fprintf(stderr, "0x%lx: after upsize (%d, %d) w: %d, h: %d\n", client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
|
||||
setAllowedActions();
|
||||
|
||||
bool place_window = True;
|
||||
if (blackbox->isStartup() || isTransient() ||
|
||||
client.normal_hint_flags & (PPosition|USPosition)) {
|
||||
|
@ -260,51 +252,56 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
place_window = False;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: after gravity (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
|
||||
// add the window's strut. note this is done *after* placing the window.
|
||||
screen->addStrut(&client.strut);
|
||||
updateStrut();
|
||||
|
||||
if (decorations & Decor_Titlebar)
|
||||
createTitlebar();
|
||||
|
||||
if (decorations & Decor_Handle)
|
||||
createHandle();
|
||||
|
||||
#ifdef SHAPE
|
||||
if (blackbox->hasShapeExtensions() && flags.shaped) {
|
||||
if (blackbox->hasShapeExtensions() && flags.shaped)
|
||||
configureShape();
|
||||
}
|
||||
#endif // SHAPE
|
||||
|
||||
windowmenu = new Windowmenu(this);
|
||||
|
||||
if (blackbox_attrib.workspace >= screen->getWorkspaceCount())
|
||||
screen->getCurrentWorkspace()->addWindow(this, place_window);
|
||||
else
|
||||
screen->getWorkspace(blackbox_attrib.workspace)->
|
||||
addWindow(this, place_window);
|
||||
|
||||
/*
|
||||
the server needs to be grabbed here to prevent client's from sending
|
||||
events while we are in the process of configuring their window.
|
||||
We hold the grab until after we are done moving the window around.
|
||||
*/
|
||||
|
||||
XGrabServer(blackbox->getXDisplay());
|
||||
|
||||
associateClientWindow();
|
||||
|
||||
blackbox->saveWindowSearch(client.window, this);
|
||||
|
||||
if (! place_window) {
|
||||
// don't need to call configure if we are letting the workspace
|
||||
// place the window
|
||||
configure(frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: after configure (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
positionWindows();
|
||||
|
||||
XUngrabServer(blackbox->getXDisplay());
|
||||
|
||||
// now that we know where to put the window and what it should look like
|
||||
// we apply the decorations
|
||||
decorate();
|
||||
|
||||
grabButtons();
|
||||
|
||||
XMapSubwindows(blackbox->getXDisplay(), frame.window);
|
||||
|
||||
// this ensures the title, buttons, and other decor are properly displayed
|
||||
redrawWindowFrame();
|
||||
|
||||
// preserve the window's initial state on first map, and its current state
|
||||
// across a restart
|
||||
unsigned long initial_state = current_state;
|
||||
|
@ -316,6 +313,7 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
client.transient_for->isStuck() != flags.stuck)
|
||||
stick();
|
||||
|
||||
// the following flags are set by blackbox native apps only
|
||||
if (flags.shaded) {
|
||||
flags.shaded = False;
|
||||
initial_state = current_state;
|
||||
|
@ -336,31 +334,6 @@ BlackboxWindow::BlackboxWindow(Blackbox *b, Window w, BScreen *s) {
|
|||
|
||||
if (flags.maximized && (functions & Func_Maximize))
|
||||
remaximize();
|
||||
|
||||
/*
|
||||
When the window is mapped (and also when its attributes are restored), the
|
||||
current_state that was set here will be used.
|
||||
It is set to Normal if the window is to be mapped or it is set to Iconic
|
||||
if the window is to be iconified.
|
||||
*Note* that for sticky windows, the same rules apply here, they are in
|
||||
fact never set to Iconic since there is no way for us to tell if a sticky
|
||||
window was iconified previously.
|
||||
*/
|
||||
|
||||
positionWindows();
|
||||
decorate();
|
||||
grabButtons();
|
||||
|
||||
XMapSubwindows(blackbox->getXDisplay(), frame.window);
|
||||
|
||||
redrawWindowFrame();
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: end of constructor (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
|
||||
|
@ -482,8 +455,10 @@ void BlackboxWindow::associateClientWindow(void) {
|
|||
|
||||
XSelectInput(blackbox->getXDisplay(), frame.plate, SubstructureRedirectMask);
|
||||
|
||||
XGrabServer(blackbox->getXDisplay());
|
||||
|
||||
/*
|
||||
note we used to grab around this call to XReparentWindow however the
|
||||
server is now grabbed before this method is called
|
||||
*/
|
||||
unsigned long event_mask = PropertyChangeMask | FocusChangeMask |
|
||||
StructureNotifyMask;
|
||||
XSelectInput(blackbox->getXDisplay(), client.window,
|
||||
|
@ -491,12 +466,9 @@ void BlackboxWindow::associateClientWindow(void) {
|
|||
XReparentWindow(blackbox->getXDisplay(), client.window, frame.plate, 0, 0);
|
||||
XSelectInput(blackbox->getXDisplay(), client.window, event_mask);
|
||||
|
||||
XUngrabServer(blackbox->getXDisplay());
|
||||
|
||||
XRaiseWindow(blackbox->getXDisplay(), frame.plate);
|
||||
XMapSubwindows(blackbox->getXDisplay(), frame.plate);
|
||||
|
||||
|
||||
#ifdef SHAPE
|
||||
if (blackbox->hasShapeExtensions()) {
|
||||
XShapeSelectInput(blackbox->getXDisplay(), client.window,
|
||||
|
@ -883,9 +855,7 @@ void BlackboxWindow::grabButtons(void) {
|
|||
|
||||
|
||||
void BlackboxWindow::ungrabButtons(void) {
|
||||
if (! screen->isSloppyFocus() || screen->doClickRaise())
|
||||
blackbox->ungrabButton(Button1, 0, frame.plate);
|
||||
|
||||
blackbox->ungrabButton(Button1, 0, frame.plate);
|
||||
blackbox->ungrabButton(Button1, ModMask, frame.window);
|
||||
blackbox->ungrabButton(Button2, ModMask, frame.window);
|
||||
blackbox->ungrabButton(Button3, ModMask, frame.window);
|
||||
|
@ -2627,12 +2597,6 @@ void BlackboxWindow::mapRequestEvent(const XMapRequestEvent *re) {
|
|||
case InactiveState:
|
||||
case ZoomState:
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: just before show (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
show();
|
||||
screen->getWorkspace(blackbox_attrib.workspace)->raiseWindow(this);
|
||||
if (isNormal()) {
|
||||
|
@ -2726,12 +2690,6 @@ void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) {
|
|||
}
|
||||
|
||||
reconfigure();
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: transient hint (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2784,12 +2742,6 @@ void BlackboxWindow::propertyNotifyEvent(const XPropertyEvent *pe) {
|
|||
if (old_rect != frame.rect)
|
||||
reconfigure();
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: normal hint (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2849,19 +2801,11 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) {
|
|||
applyGravity(req);
|
||||
}
|
||||
|
||||
if (cr->value_mask & CWWidth) {
|
||||
if (cr->value_mask & CWWidth)
|
||||
req.setWidth(cr->width + frame.margin.left + frame.margin.right);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: new width - %d\n", client.window, cr->width);
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
if (cr->value_mask & CWHeight) {
|
||||
if (cr->value_mask & CWHeight)
|
||||
req.setHeight(cr->height + frame.margin.top + frame.margin.bottom);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: new height - %d\n", client.window, cr->height);
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
configure(req.x(), req.y(), req.width(), req.height());
|
||||
}
|
||||
|
@ -2880,13 +2824,6 @@ void BlackboxWindow::configureRequestEvent(const XConfigureRequestEvent *cr) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "0x%lx: change request (%d, %d) w: %d, h: %d\n",
|
||||
client.window,
|
||||
frame.rect.x(), frame.rect.y(),
|
||||
frame.rect.width(), frame.rect.height());
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
|
||||
|
@ -3564,7 +3501,8 @@ void BlackboxWindow::restore(bool remap) {
|
|||
XSelectInput(blackbox->getXDisplay(), frame.plate, NoEventMask);
|
||||
|
||||
// do not leave a shaded window as an icon unless it was an icon
|
||||
if (flags.shaded && ! flags.iconic) setState(NormalState);
|
||||
if (flags.shaded && ! flags.iconic)
|
||||
setState(NormalState);
|
||||
|
||||
restoreGravity(client.rect);
|
||||
|
||||
|
|
Loading…
Reference in a new issue