Xlib. 프레임은 클라이언트 창으로 전송된 입력에 응답합니다.

Xlib. 프레임은 클라이언트 창으로 전송된 입력에 응답합니다.

다음을 사용하여 프레임을 만들고 있습니다.

frame = XCreateSimpleWindow(display, root, x_window_attributes.x, x_window_attributes.y, x_window_attributes.width, x_window_attributes.height + window_bar_height, border_width, border_color, background_color);
XSelectInput(display, frame, SubstructureRedirectMask | SubstructureNotifyMask);
XAddToSaveSet(display, window);
XReparentWindow(display, window, frame, 0, 20);
XMapWindow(display, frame);

//Map events
XGrabButton(display, Button1, 0, frame, false, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(display, Button1, 0, frame, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(display, Button3, 0, frame, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);

이상적으로 매핑된 이벤트는 사용자가 프레임워크와 직접 상호 작용할 때만 작동합니다. 그러나 사용자가 클라이언트 창과 상호 작용할 때도 작동합니다. 즉, 프레임을 드래그하는 대신 어디든 드래그할 수 있으며 여전히 창을 이동/크기 조정합니다.

어떻게 프레임으로만 제한할 수 있나요? 아마도 SubtstructRedirectMask가 이 문제의 원인일 것이라고 생각했지만 이를 제거한 후에도 동일한 문제가 발생했습니다.

도움을 주시면 감사하겠습니다!

답변1

이 질문은 Xlib의 마스킹 및 입력 처리에 대한 이해가 부족하여 발생합니다. 이것을 수많은 시행착오를 통해 배워야 했기 때문에 이제 목수염이 자라기 시작할지도 모르겠습니다. 수염을 깔끔하게 유지하고 싶은 분들을 위해 다음과 같은 답변을 드립니다.

이제 마스크(예 SubtstructureRedirectMask: )에 대해 걱정하지 마세요. 입력을 받아야 한다는 점만 알아두세요.

프레임의 경우 원래 계획은 클라이언트 창과 동일한 크기에 일부를 더한 프레임을 만든 다음 이를 오프셋하는 것이었습니다. 예를 들어 클라이언트 창 높이가 800픽셀인 경우 프레임 높이를 820픽셀로 설정하고 클라이언트 창을 20픽셀만큼 오프셋한 다음 제목 표시줄에 위쪽 20픽셀을 사용합니다. 클라이언트 창이 프레임의 나머지 부분에 대한 입력을 차단하고 노출된 상위 20px만 이에 반응하도록 하려고 합니다*. 그러나 그렇지 않습니다. 입력은 클라이언트 창을 통해 직접 전달되며 전체 프레임(제목 표시줄 영역 및 클라이언트 창 영역)이 이에 응답합니다.

이 문제를 피하기 위해 코드를 확인하고 다른 창 관리자와 테스트한 후 별도의 제목 표시줄 창을 만들기로 결정했습니다. 이제 window클라이언트 창을 나타내는 , frame프레임(부모로 필요)을 나타내는 , titlebar제목 표시줄을 나타내는 가 있습니다 .

이전 코드는 다음으로 대체되었습니다.

XGrabButton(display, Button1, 0, titlebar, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(display, Button3, 0, titlebar, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);

이제 titlebar위의 하나만 window입력 이동에 관심이 있습니다. 프레임과 클라이언트 창의 크기를 조정하고 이동하기 위해 모든 것을 보상하기 위해 몇 가지 간단한 계산을 수행했습니다.

관련 정보