KDE를 보면 비활성일 때도 투명하게 되는 장면이 있던데, 따라해보고 싶어서 찾아봤다.

투명하게 그리는 건 compositor.c의 paint_screen이 담당하던데, 지금은 이동중이거나 크기를 바꿀 때만 적용되는 거라서 조건이 grab_window이며, grab_op이 resize나 move일 경우에 투명하게 그리도록 되어 있다.

내가 하고 싶은 건 이를 테면 포커스가 있는 창만 안 투명하고 나머지는 다 투명한 거다. 포커스가 있는 창을 어떻게 구분할까 했는데 실제로 그리는 동작이 while 루프를 통해 이루어지고 있었다. compositor_windows라는 연결 목록을 뒤에서부터 훑어서 뒤에서부터 창을 그려오는 식이었다. 그러면 앞에 있어야 될 창이 나중에 그려지면서 뒤에 있어야 될 창을 덮어쓴다는 거겠지. 그래서 tmp라는 그 포인터와 원래 목록의 최초를 가리킬 것으로 생각되는 compositor_windows를 비교하도록 했다. 실패.

이건 아닌가 해서 찾아보니 meat-display 개체에 focus_window라는 속성이 있다. 메타시티 내부에서 마지막으로 포커스 처리를 했던 것으로 내가 원하는 목적에 딱 맞았다.

focus_window가 아닐 경우에는 투명하게 그리도록 조건을 바꿨다. 근데 포커스가 바뀐 즉시 투명이 적용되질 않아서 보니 paint_screen이 실행되는 게 애초에 do_repair가 호출되어야 하고, 그 조건은 damage가 발생하는 거였다. 찾아보니까 meta_compositor_damage_window라는 함수가 있어서 window.c에서 FocusOut 이벤트일 때 focus_window를 초기화하기 전에 불러줬다.

일단 기능은 되는데, 포커스가 바뀔 때 이벤트를 한 번 돌고, paint_screen 자체도 창 전체를 다시 그리기 때문에 한 박자 느리다.

가장 좋은 건 딴 거 없이 그 창만 딱 다시 그릴 수 있는 건데 그건 어떻게 할지 아직 모르겠다. window.c 영역에서 쓸 수 있는 함수로 send_configure_notify나 meta_window_move_resize_now 같은 걸 써보긴 했는데 아무래도 직접 그 영역만 딱 그리지는 않는지 아무 결과도 안 나온다.



더 고려해야 될 점이 있는데, 지금은 조건을 너무 단순하게 줘서, 패널도 투명하게 된다. 특수한 창은 비껴가도록 해야 한다.

transset-df를 응용한 어떤 스크립트 설명을 보니까 정확히 내가 원하는 거 같더라. 나중에 살펴봐야지.

+ Recent posts