2009-07-21 3 views
11

내가 쓰는 응용 프로그램 (AllTray)의 특정 선택 항목에 게시 된 WM_DELETE_WINDOW 메시지를 가로 채고 싶습니다. 따라서받은 응용 프로그램 대신 해당 메시지를 처리 ​​할 수 ​​있습니다. 가능하다면 현재 GDK 레벨 via gdk_display_add_client_message_filter에서 이것을 시도하고 있습니다 만, Xlib 솔루션이 있으면 만족할 것입니다. 그것 은 가능한 것 같아 것 같습니다,하지만 난 단지 내가 어떻게 성공적으로 그것을 이해하고있는 것 같지 않습니다.X11에서 WM_DELETE_WINDOW를 가로채는가?

현재, 나는 the first one 아무것도하지 않는다, 나는이 알아 낸 얻기 위해 사용하는 것을 시도하고있다 (C로 작성) 두 개의 프로그램을 가지고 있지만 윈도우를 생성하고 그 메시지를 잡으려고에 대한 WM_DELETE_WINDOWthe second one 시도를 알고 등록 그렇게하는 데 실패하는 것 같습니다. 그것은 정확하게 아무것도하지 않는 것처럼 보입니다. 이 문서가 잘못되었다는 것을 이해하고 있습니까? 아니면 내가해야 할 일이 있습니까? (또는 GDK를 완전히 사용하지 않아야합니까?)

배경은 다음과 같습니다. AllTray를 다시 쓰기 전에는 마우스 버튼을 X 버튼 자체에서 가로 챈 것을 시도하는 것처럼 보입니다. 일부 창 관리자의 경우이 작업은 제대로 작동하고 다른 작업은 전혀 작동하지 않는 경우도 있었고 다른 경우에는 사용자가 수동으로 구성하고 창이 닫히는 단추가 있던 AllTray를 지시해야했습니다. 내가 찾고있는 것은 LD_LIBRARY_PRELOAD을 포함하지 않고 현재 표준을 따르는 모든 윈도우 관리자/응용 프로그램 조합에 사용할 수있는 솔루션이며 창이 닫히면 WM_DELETE_WINDOW ClientMessage를 보냅니다.

업데이트 : 아직 답변을 찾고 있습니다. 지금 내가 취하는 경로는 창을 다시 만들고 그것을 관리하려고 시도하는 것이지만, 나는 그것을 작동시키지 못합니다. 보육을받을 때, 나는 어떤 식 으로든 그것을 되 찾을 수없는 것 같습니다. 나는 아주 근본적인 것을 놓치고 있을지 모르지만 실제로 화면으로 다시 가져 오는 방법을 실제로 내 자신의 창으로 보이게 만드는 방법을 알아낼 수는 없습니다.

업데이트 2 : 좋아, 그래서 나는 다른 벽돌 벽에 부딪쳤다. X 서버 설명서에서는 MapNotify 및 ReparentNotify 이벤트를 모두 수신하도록 윈도우의 이벤트 마스크에서 StructureNotifyMask를 설정한다고 설명합니다. 나는 어느 쪽인가받는 것에 흥미가있을 것이다. 현재 나의 생각은 이벤트 수신자 역할을하는 창을 작성한 다음 흥미로운 일들에 대한 이벤트를 얻었을 때 생성하고 보충함으로써 행동을 취하는 것입니다. 그러나 이것은 단순히 작동하지 않는 것 같습니다. 실제로 수신되는 유일한 이벤트는 PropertyNotify 이벤트입니다. 따라서이 경로는별로 좋지 않은 것 같습니다.

+0

나는 자신의 최상위 내부 창을 보충하고 어떤 이벤트를 필터링 할 수있을 것이라고 생각합니까? 네가 현재 시도하고있는 방식이 효과가 있다고 생각하지 않는다. – wrt

+0

이렇게하는 데 단점이 있습니까? 즉, 특히 XDND 같은 것을 간섭하게하는 요소가 무엇입니까? 휴대용 아이디어입니까? (예 : 응용 프로그램이나 창 관리자를 중단시키지 않습니까?) 나는 그것에 관한 정보를 거의 찾을 수없는 것 같습니다. 나는 또한 각각의 새로운 클라이언트 윈도우에 대해 하나의 새로운 "부모"윈도우를 만들어야한다는 것을 의미한다고 가정합니다. –

답변

1

불행히도이 질문에 대한 최선의 대답은 일련의 응답이 아닙니다. 거기를 달성 할 수있는 방법은 기술적으로,하지만 그들은 모두 그들이 매우 비실용적 낙하 있습니다

  1. 앞뒤로 응용 프로그램과 X 서버 사이의 모든 X11 프로토콜 메시지를 전달하는 응용 프로그램에 대한 X11 프록시를 생성합니다. 그러면 프록시가 흥미로운 메시지를 걸러냅니다. 단점은 이것이 아주 작은 단일 기능에 대한 엄청난 오버 헤드이며 X11 프로토콜은 복잡하다는 것입니다. 또한 의도하지 않은 결과가 발생할 수 있으며, 이는 더 매력없는 선택입니다.
  2. 창 관리자와 "흥미로운"클라이언트 응용 프로그램 사이의 중개자 역할을하는 표준 응용 프로그램으로 시작합니다. XDnD와 같은 몇 가지 문제가 발생합니다. 실제로 프록시는 X11 프로토콜 수준이 아닌 Window 수준에 있다는 점을 제외하면 첫 번째 옵션과 다르지 않습니다.
  3. 휴대용이 아닌 LD_PRELOAD 라이브러리 트릭을 사용하십시오. 이것은 여러 개의 단점을 가지고 있습니다 :
    1. 동적 링커에서는 동적이 아닙니다. 모든 동적 링커가 LD_PRELOAD을 지원하며 UNIX 계열 시스템에서도 지원되지는 않습니다.
    2. 운영 체제간에 호환되지 않는 기능이 있습니다. 모든 운영 체제가 기능이 뛰어난 동적 링커를 지원하는 것은 아닙니다.
    3. 네트워크 투명성이 깨집니다. 공유 개체/동적 링크 라이브러리는 실행중인 자식 프로세스로 호스트에 있어야합니다.
    4. 모든 X11 응용 프로그램이 Xlib를 사용하는 것은 아닙니다. 응용 프로그램이 X11과 대화하는 데 사용할 수있는 각 라이브러리에 대해 하나의 LD_PRELOAD 모듈을 작성해야합니다.
    5. X와 통신하기 위해 공유 객체 나 DLL을 사용할 수 없기 때문에 모든 응용 프로그램이 지원하는 링커에서 실행 되더라도 모든 응용 프로그램이 LD_PRELOAD의 영향을받을 수있는 것은 아닙니다. 예를 들어, Java 자체로 작성된 X11 프로토콜 라이브러리를 사용하는 Java 응용 프로그램을 생각해보십시오.
    6. 일부 유닉스 계열 운영 체제에서 LD_PRELOAD 라이브러리는 setuid/setgid 프로그램과 함께 사용하려면 setuid/setgid 여야합니다. 이것은 잠재적 인 보안 취약점입니다.
    7. 나는 그것이 내가 생각할 수없는 단점이라고 확신한다.
  4. X 윈도우 시스템의 확장 기능을 구현하십시오. X11 구현 중에는 이식성이 없으며 복잡하고 복잡합니다. 모두 빠져 나오고 절대적으로 의문입니다.
  5. 창 관리자에 대한 확장 또는 플러그인을 구현하십시오. 창 관리자에 대한 의견이있는만큼 많은 창 관리자가 있으므로 전체적으로 실행 불가능합니다.

궁극적으로 완전히 다른 메커니즘을 사용하여 최종적으로 목표를 달성 할 수있었습니다. 관심있는 사람은 the git master branch available on github을 포함하여 AllTray 0.7.5.1 이상 버전의 Close-to-Tray 지원을 참조하십시오.

11

나는 X11을 모른다. 그러나 나는 "Intercept WM_DELETE_WINDOW X11"을 키워드로 사용하여 googled했다. 발견 된 17k - MarkMailMplayer-commits r154 - trunk/libvo. 두 경우 모두 똑같은 일을합니다. static int x11_check_events()static void x11_init()

/* This is used to intercept window closing requests. */ 
static Atom wm_delete_window; 

, 다음

XMapWindow(display, win); 
wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); 
XSetWMProtocols(display, win, &wm_delete_window, 1); 

,

XEvent Event; 
while (XPending(display)) { 
    XNextEvent(display, &Event); 
    if (Event.type == ClientMessage) { 
     if ((Atom)Event.xclient.data.l[0] == wm_delete_window) { 
      /* your code here */ 
     } 
    } 
} 

XInternAtom, XSetWMProtocolsXNextEvent를 참조하십시오.사용자가 우리의 X11 응용 프로그램에 닫기 버튼 [x]를 클릭하면 우리는 당신이 정말 종료할까요 그것은 "는 질문 AA 대화 상자를 팝업 할

: 나는 위의 쓴 후

, 나는 Handling window close in an X11 app 발견 ? ". 이것은 일반 X 앱입니다. 멋진 GTK 또는 QT 위젯이 없습니다 여기에. 그래서 "창문을 닫는 중 "이라는 메시지를 잡는 방법은 무엇입니까?

대답은 그것으로 WM_DELETE_WINDOW 메시지 를 등록 XSetWMProtocols 및 를 호출하여 우리가이 이벤트에 관심이 창 관리자를 알려주는 것이다. 그런 다음 누군가가 창을 닫으려고하면 메시지를 창 관리자가 보내고 닫히지 않으면 메시지가 표시됩니다. 여기에 예제가 있습니다. 내 이전 제안에 정교

// example.cpp 
#include <X11/Xlib.h> 
#include <X11/Xatom.h> 
#include <iostream> 

int main() 
{ 
    Display* display = XOpenDisplay(NULL); 
    Window window = XCreateSimpleWindow(display, 
             DefaultRootWindow(display), 
             0, 0, 
             500, 400, 
             0, 
             0, 0); 

    // register interest in the delete window message 
    Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); 
    XSetWMProtocols(display, window, &wmDeleteMessage, 1); 

    std::cout << "Starting up..." << std::endl; 
    XMapWindow(display, window); 

    while (true) { 
     XEvent event; 
     XNextEvent(display, &event); 

     if (event.type == ClientMessage && 
      event.xclient.data.l[0] == wmDeleteMessage) { 
     std::cout << "Shutting down now!!!" << std::endl; 
     break; 
     } 
    } 

    XCloseDisplay(display); 
    return 0; 
} 
+0

그것은 내 문제를 해결할 수만 있다면 좋을 것입니다. 문제는 내가 창을 소유하고있어서 이벤트를 받고 싶지 않다는 것입니다. 내가 잘 할 수 있고 (위의 방법 중 하나를 수행 할 것임) 문제는 내 응용 프로그램이 다른 창을 차단해야한다는 것입니다. Windows가 아닌, 내가 만든 것이 아닙니다. 나는 첫 번째 주석 작성자가 강제로 창문을 보충하여 무엇을 의미하는지 알아 내려고 노력하고 있지만 아직 실제로 작동하도록 만들지 않았습니다. 나는 며칠 동안 인터넷 검색을 해왔다. 그래서 여기에 왔어요. –

+0

http://tronche.com/gui/x/xlib/window-and-session-manager/XReparentWindow.html을 이미 읽은 것으로 가정합니다. –

+0

실제로 있습니다. 나는 그것이 올바르게 작동하도록하기 위해 무엇을해야하는지 아직 확실하지 않다. 나는 윈도우를 부모가되기 위해 관리했지만, 일을 만들기위한 나의 목표를 달성 할 수 없기 때문에 뭔가를 놓치고 있어야합니다. :// 실제로 필자의 책상 위에 Xlib 레퍼런스가있다. 필자는이 것을 알아보기 위해 반복적으로 빗질 해왔다. :/ –

0

확인은, 당신은 XEmbed을 조사 할 수 있습니다. 적어도, 시도해 볼만한 아이디어를 줄 수 있습니다.

오류가 발생하는 경우 다른 유사한 소프트웨어 (예 : wmdock 또는 GtkPlug/GtkSocket 구현 방법)를 살펴 보았습니다.하지만 두 경우 모두 명시 적 지원이 애플리케이션에 필요하다고 생각합니다.

희망이 더 도움이됩니다.

+0

한 번에이 실험을했습니다. 그러나, 그것은 매우 신뢰할 수 없었다. 프로덕션 프로그램에 부적합한만큼 신뢰성이 떨어졌습니다. 다행히도 내가 생각한 최종 목표를 달성하기위한 또 다른 방법을 찾았습니다. –

0

윈도우 관리자가 클라이언트와 통신하는 방법을 알려주는 ICCCM을 읽어야합니다. 대부분의 WM은 프레임 워크 창을 만들어서 상위 레벨 창을 보충하여 보냅니다. 따라서, 귀하의 부모가 WM과 귀하의 클라이언트 윈도우가 알고있는 관계를 깨뜨릴 수 있다면.

+1

감사합니다. 나는 ICCCM과 X11에 대해 좀 더 자세히 읽었다. 보육은 일을 많이하지 않는 한 옵션이 아닙니다. Old AllTray는 속임수를 사용하여 공정에서 많은 것을 깨뜨 렸습니다. 예 : XDnD. –

관련 문제