⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wm_state.c

📁 基于linux的DVD播放器程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    // We have to be unmapped to change motif decoration hints         withdraw_window(dpy, win);        remove_motif_decorations(dpy, win);        XSetWMNormalHints(dpy, win, sizehints);    XFree(sizehints);    XMapWindow(dpy, win);        /* wait for the window to be mapped */        do {      XNextEvent(dpy, &ev);    } while(ev.type != MapNotify);        /* remove any outstanding configure_notifies */    XSync(dpy, True);                // Try to resize, place the window at correct place and on top            XGetWindowAttributes(dpy, win, &attrs);        DpyInfoGetScreenOffset(dpy, XScreenNumberOfScreen(attrs.screen),			   &win_changes.x, &win_changes.y);        DpyInfoGetResolution(dpy, XScreenNumberOfScreen(attrs.screen),			 &win_changes.width, &win_changes.height);        win_changes.stack_mode = Above;    DNOTE("Placing window at %d,%d with size %d,%d\n",	  win_changes.x, win_changes.y,	  win_changes.width, win_changes.height);    XReconfigureWMWindow(dpy, win, 0, CWX | CWY |			 CWWidth | CWHeight |			 CWStackMode,			 &win_changes);                        //todo: check if these are correct and how to detect a kwm#if 0        /* Now try to set KWM hints */    WM_HINTS = XInternAtom(mydisplay, "KWM_WIN_DECORATION", True);    if(WM_HINTS != None) {      long KWMHints = 0;            XChangeProperty(mydisplay, window.win,		      WM_HINTS, WM_HINTS, 32,		      PropModeReplace,		      (unsigned char *)&KWMHints,		      sizeof(KWMHints)/sizeof(long));      found_wm = 1;    }        /* Now try to unset KWM hints */    WM_HINTS = XInternAtom(mydisplay, "KWM_WIN_DECORATION", True);    if(WM_HINTS != None) {      XDeleteProperty(mydisplay, window.win, WM_HINTS);      found_wm = 1;    }        #endif        // If we have a gnome compliant wm that supports layers, put    // us above the dock/panel        if(gnome_wm_layers) {      XEvent ev;      ev.type = ClientMessage;      ev.xclient.window = win;      ev.xclient.message_type = XInternAtom(dpy, "_WIN_LAYER", True);      ev.xclient.format = 32;      ev.xclient.data.l[0] = 10;      XSendEvent(dpy, DefaultRootWindow(dpy), False,		 SubstructureNotifyMask, &ev);    } else {      if(wm_name != NULL) {	if(strcmp(wm_name, "KWin") == 0) {	  XEvent ev;	  ev.type = ClientMessage;	  ev.xclient.window = win;	  ev.xclient.message_type = XInternAtom(dpy, "_NET_WM_STATE", True);	  ev.xclient.format = 32;	  ev.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD	  ev.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);	  ev.xclient.data.l[2] = 0;	  	  XSendEvent(dpy, DefaultRootWindow(dpy), False,		     SubstructureNotifyMask, &ev);	}      }    }        // Wait for a configure notify    do {      XNextEvent(dpy, &ev);    } while(ev.type != ConfigureNotify);        // save the configure event so we can return it    ret_ev = ev;        calc_coords(dpy, win, &x, &y, &ev);    for(n = 0; n < 10; n++) {      while(XCheckTypedEvent(dpy, ConfigureNotify, &ev) == True) {	ret_ev = ev;	calc_coords(dpy, win, &x, &y, &ev);      }      if(abs(x-win_changes.x) < 100 &&	 abs(y-win_changes.y) < 100) {	break;      }      usleep(100000);    }        //DNOTE("no more configure notify\n");    //try to move one more time, maybe we didn't get all configure events?    if(x != win_changes.x || y != win_changes.y) {      DNOTE("%s", "window is not at screen start. Trying to move again\n");            XSync(dpy, True);      XReconfigureWMWindow(dpy, win, 0, CWX | CWY,			   &win_changes);      /*            do {	XNextEvent(dpy, &ev);      } while(ev.type != ConfigureNotify);            ret_ev = ev;            calc_coords(dpy, win, &x, &y, &ev);      */      while(XCheckTypedEvent(dpy, ConfigureNotify, &ev) == True) {	ret_ev = ev;	calc_coords(dpy, win, &x, &y, &ev);      }    }     // ugly hack, but what can you do when the wm's not removing decorations    //  if we don't end up at (win_changes.x, win_changes.y)    //  try to compensate and move one more time    if((x != win_changes.x || y != win_changes.y) &&       abs(x - win_changes.x) < 100 && abs(y - win_changes.y) < 100) {      XWindowChanges win_compensate;      win_compensate.x = win_changes.x+win_changes.x-x;      win_compensate.y = win_changes.y+win_changes.y-y;      DNOTE("%s", "window is not at screen start\n");      DNOTE("Compensating by moving to x: %d= %d+%d-%d, y: %d= %d+%d-%d\n",	    win_compensate.x, win_changes.x, win_changes.x, x,	    win_compensate.y, win_changes.y, win_changes.y, y);            XSync(dpy, True);      XReconfigureWMWindow(dpy, win, 0, CWX | CWY,			   &win_compensate);            do {	XNextEvent(dpy, &ev);      } while(ev.type != ConfigureNotify);            ret_ev = ev;            calc_coords(dpy, win, &x, &y, &ev);            while(XCheckTypedEvent(dpy, ConfigureNotify, &ev) == True) {	ret_ev = ev;	calc_coords(dpy, win, &x, &y, &ev);      }            if(x != win_changes.x || y != win_changes.y) {	DNOTE("Couldn't place window at %d,%d\n",	      win_changes.x, win_changes.y);	DNOTE("Window is at %d, %d\n",	      x, y);      } else {	//DNOTE("Fixed, window is now at %d,%d\n", win_changes.x, win_changes.y);      }          }            XPutBackEvent(dpy, &ret_ev);  } else {    // ewmh_state_fullscreen is supported    XEvent ev;        ev.type = ClientMessage;    ev.xclient.window = win;    ev.xclient.message_type = XInternAtom(dpy, "_NET_WM_STATE", False);    ev.xclient.format = 32;    ev.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD not an atom just a define    ev.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);    ev.xclient.data.l[2] = 0;        XSendEvent(dpy, DefaultRootWindow(dpy), False,	       SubstructureNotifyMask, &ev);          }    current_state = WINDOW_STATE_FULLSCREEN;  }static void switch_to_normal_state(Display *dpy, Window win){  XEvent ev;  XSizeHints *sizehints;  if(!has_ewmh_state_fullscreen) {    // We don't want to have to replace the window manually when remapping it    sizehints = XAllocSizeHints();    sizehints->flags = USPosition;    sizehints->x = 0; // obsolete but should be set in case    sizehints->y = 0; // an old wm is used        // We have to be unmapped to change motif decoration hints     withdraw_window(dpy, win);        disable_motif_decorations(dpy, win);        XSetWMNormalHints(dpy, win, sizehints);    XFree(sizehints);    XMapWindow(dpy, win);        /* wait for the window to be mapped */        do {      XNextEvent(dpy, &ev);    } while(ev.type != MapNotify);        /* remove any outstanding configure_notifies */    XSync(dpy, True);                // get us back to the position and size we had before fullscreen    restore_normal_geometry(dpy, win);        // If we have a gnome compliant wm that supports layers, put    // us in the normal layer        if(gnome_wm_layers) {      XEvent ev;      ev.type = ClientMessage;      ev.xclient.window = win;      ev.xclient.message_type = XInternAtom(dpy, "_WIN_LAYER", True);      ev.xclient.format = 32;      ev.xclient.data.l[0] = 4;      XSendEvent(dpy, DefaultRootWindow(dpy), False,		 SubstructureNotifyMask, &ev);    } else {      if(wm_name != NULL) {	if(strcmp(wm_name, "KWin") == 0) {	  XEvent ev;	  ev.type = ClientMessage;	  ev.xclient.window = win;	  ev.xclient.message_type = XInternAtom(dpy, "_NET_WM_STATE", True);	  ev.xclient.format = 32;	  ev.xclient.data.l[0] = 0; // _NET_WM_STATE_REMOVE	  ev.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_STAYS_ON_TOP", False);	  ev.xclient.data.l[2] = 0;	  	  XSendEvent(dpy, DefaultRootWindow(dpy), False,		     SubstructureNotifyMask, &ev);	}      }    }  } else {    // ewmh_state_fullscreen is supported    XEvent ev;        ev.type = ClientMessage;    ev.xclient.window = win;    ev.xclient.message_type = XInternAtom(dpy, "_NET_WM_STATE", False);    ev.xclient.format = 32;    ev.xclient.data.l[0] = 0; //_NET_WM_STATE_REMOVE not an atom just a define    ev.xclient.data.l[1] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);    ev.xclient.data.l[2] = 0;        XSendEvent(dpy, DefaultRootWindow(dpy), False,	       SubstructureNotifyMask, &ev);  }  current_state = WINDOW_STATE_NORMAL;}static int xprop_errorhandler(Display *dpy, XErrorEvent *ev){  if(ev->serial == req_serial) {    /* this is an error to the XGetWindowProperty request     * most probable the window specified by the property     * _WIN_SUPPORTING_WM_CHECK on the root window no longer exists     */    WARNING("%s", "xprop_errhandler: error in XGetWindowProperty\n");    return 0;  } else {    /* if we get another error we should handle it,     * so we give it to the previous errorhandler     */    ERROR("%s", "xprop_errhandler: unexpected error\n");    return prev_xerrhandler(dpy, ev);  }}static int check_for_gnome_wm(Display *dpy){  Atom atom;  Atom type_return;  int format_return;  unsigned long nitems_return;  unsigned long bytes_after_return;  unsigned char *prop_return = NULL;  Window win_id;  int status;  atom = XInternAtom(dpy, "_WIN_SUPPORTING_WM_CHECK", True);  if(atom == None) {    return 0;  }    if(XGetWindowProperty(dpy, DefaultRootWindow(dpy), atom, 0,		     1, False, XA_CARDINAL,		     &type_return, &format_return, &nitems_return,			&bytes_after_return, &prop_return) != Success) {    WARNING("%s", "XGetWindowProperty failed in check_for_gnome\n");    return 0;  }    if(type_return == None) {    DNOTE("%s", "check_for_gnome: _WIN_SUPPORTING_WM_CHECK does not exist\n");    return 0;  }  if(type_return != XA_CARDINAL) {    WARNING("%s", "check_for_gnome: _WIN_SUPPORTING_WM_CHECK has wrong type\n");    if(prop_return != NULL) {      XFree(prop_return);    }    return 0;  }  if(type_return == XA_CARDINAL) {    //DNOTE("check_for_gnome: format: %d\n", format_return);    //DNOTE("check_for_gnome: nitmes: %ld\n", nitems_return);    //DNOTE("check_for_gnome: bytes_after: %ld\n", bytes_after_return);    if(format_return == 32 && nitems_return == 1 && bytes_after_return == 0) {      win_id = *(long *)prop_return;      //DNOTE("win_id: %ld\n", win_id);      XFree(prop_return);      prop_return = NULL;            /* make sure we don't have any unhandled errors */      XSync(dpy, False);      /* set error handler so we can check if XGetWindowProperty failed */      prev_xerrhandler = XSetErrorHandler(xprop_errorhandler);      /* get the serial of the XGetWindowProperty request */      req_serial = NextRequest(dpy);      /* try to get property       * this can fail if we have a property with the win_id on the       * root window, but the win_id is no longer valid.       * example: we have had a gnome wm running but are now running       * a non gnome wm.       * question: shouldn't the gnome wm remove the property from       * the root window when exiting ? bug in sawfish?       */      status = XGetWindowProperty(dpy, win_id, atom, 0,				  1, False, XA_CARDINAL,				  &type_return, &format_return, &nitems_return,				  &bytes_after_return, &prop_return);      /* make sure XGetWindowProperty has been processed and any errors	 have been returned to us */      XSync(dpy, False);            /* revert to the previous xerrorhandler */      XSetErrorHandler(prev_xerrhandler);      if(status != Success) {	WARNING("%s", "XGetWindowProperty failed in check_for_gnome\n");	return 0;      }            if(type_return == None) {	DNOTE("%s", "check_for_gnome: _WIN_SUPPORTING_WM_CHECK does not exist in specified win\n");	return 0;      }            if(type_return != XA_CARDINAL) {	WARNING("%s", "check_for_gnome: property has wrong type\n");	if(prop_return != NULL) {	  XFree(prop_return);	}	return 0;      }            if(type_return == XA_CARDINAL) {	//DNOTE("check_for_gnome: format: %d\n", format_return);	//DNOTE("check_for_gnome: nitmes: %ld\n", nitems_return);	//DNOTE("check_for_gnome: bytes_after: %ld\n", bytes_after_return);	if(format_return == 32 && nitems_return == 1 &&	   bytes_after_return == 0) {	  //DNOTE("win_id: %ld\n", *(long *)prop_return);	  if(win_id == *(long *)prop_return) {	    // We have successfully detected a GNOME compliant Window Manager	    XFree(prop_return);	    return 1;	  }	}	XFree(prop_return);	return 0;      }    }    XFree(prop_return);    return 0;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -