1 /** WARNING: This file is intended to be part of panel module only ;) */
11 static void panel_window_focus (PanelWindow
* panel
);
12 static void update_window_pos (PanelWindow
* panel
);
13 static int fix_border (PanelWindow
* panel
);
14 static void update_pos (PanelWindow
* panel
);
15 static gboolean
show (PanelWindow
* panel
);
16 static gboolean
hide (PanelWindow
* panel
);
17 static gboolean
present (PanelWindow
* panel
);
18 static void set_Gravity (PanelWindow
* panel
);
21 void panel_window_focus (PanelWindow
* panel
)
23 #ifdef GDK_WINDOWING_X11
24 XClientMessageEvent event
;
26 event
.type
= ClientMessage
;
27 event
.window
= GDK_WINDOW_XID (GTK_WIDGET (panel
->win
)->window
);
28 event
.message_type
= gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");
32 gdk_error_trap_push ();
34 XSendEvent (GDK_DISPLAY (), GDK_ROOT_WINDOW (), False
,
35 StructureNotifyMask
, (XEvent
*) &event
);
39 if (gdk_error_trap_pop () != 0)
40 g_critical ("Failed to focus panel window");
43 gtk_window_present (GTK_WINDOW (panel
->win
));
47 void update_window_pos (PanelWindow
* panel
)
49 if (panel
->docking
.visible
)
50 gtk_window_move (GTK_WINDOW (panel
->win
), panel
->pos
.x
, panel
->pos
.y
);
51 else gtk_window_move (GTK_WINDOW (panel
->win
), panel
->pos
.hidden
.x
, panel
->pos
.hidden
.y
);
55 int fix_border (PanelWindow
* panel
)
57 switch (panel
->docking
.side
) {
58 case SIDE_LEFT
: return (panel
->docking
.border
< panel
->size
.w
) ? panel
->docking
.border
: panel
->size
.w
;
59 case SIDE_RIGHT
: return (panel
->docking
.border
< panel
->size
.w
) ? panel
->docking
.border
: panel
->size
.w
;
60 case SIDE_TOP
: return (panel
->docking
.border
< panel
->size
.h
) ? panel
->docking
.border
: panel
->size
.h
;
61 case SIDE_BOTTOM
: return (panel
->docking
.border
< panel
->size
.h
) ? panel
->docking
.border
: panel
->size
.h
;
66 int docked_pos_to_pixels (int range
, int len
, double pos
)
67 { return (range
< len
) ? 0 : (range
- len
) * pos
; }
70 void update_pos (PanelWindow
* panel
)
72 g_print ("update_pos: ");
73 switch (panel
->docking
.side
) {
75 g_print ("side = NONE, ");
80 panel
->pos
.y
= docked_pos_to_pixels (panel
->scr
.h
, panel
->size
.h
, panel
->docking
.pos
);
81 panel
->pos
.hidden
.x
= fix_border(panel
) - panel
->size
.w
;
82 panel
->pos
.hidden
.y
= panel
->pos
.y
;
83 g_print ("side = LEFT, ");
87 panel
->pos
.x
= panel
->scr
.w
- panel
->size
.w
;
88 panel
->pos
.y
= docked_pos_to_pixels (panel
->scr
.h
, panel
->size
.h
, panel
->docking
.pos
);
89 panel
->pos
.hidden
.x
= panel
->scr
.w
- fix_border(panel
);
90 panel
->pos
.hidden
.y
= panel
->pos
.y
;
91 g_print ("side = RIGHT, ");
96 panel
->pos
.x
= docked_pos_to_pixels (panel
->scr
.w
, panel
->size
.w
, panel
->docking
.pos
);
97 panel
->pos
.hidden
.y
= fix_border(panel
) - panel
->size
.h
;
98 panel
->pos
.hidden
.x
= panel
->pos
.x
;
99 g_print ("side = TOP, ");
103 panel
->pos
.y
= panel
->scr
.h
- panel
->size
.h
;
104 panel
->pos
.x
= docked_pos_to_pixels (panel
->scr
.w
, panel
->size
.w
, panel
->docking
.pos
);
105 panel
->pos
.hidden
.y
= panel
->scr
.h
- fix_border(panel
);
106 panel
->pos
.hidden
.x
= panel
->pos
.x
;
107 g_print ("side = BOTTOM, ");
110 default: g_print ("Unknown side, ");
112 g_print ("scr.W = %i, scr.H = %i, size = %i, pos = %f, X = %i, Y = %i, hidden_X = %i, hidden_Y = %i, border = %i\n",
113 panel
->scr
.w
, panel
->scr
.h
,
114 panel
->size
.w
, panel
->docking
.pos
,
115 panel
->pos
.x
, panel
->pos
.y
,
116 panel
->pos
.hidden
.x
, panel
->pos
.hidden
.y
,
121 gboolean
show (PanelWindow
* panel
)
123 panel
->docking
.visible
= TRUE
;
124 update_window_pos (panel
);
129 gboolean
hide (PanelWindow
* panel
)
131 panel
->docking
.visible
= FALSE
;
132 update_window_pos (panel
);
137 gboolean
present (PanelWindow
* panel
)
140 panel_window_focus (panel
);
141 if (! gtk_window_is_active (GTK_WINDOW (panel
->win
)) )
142 g_print ("Failed to get focus\n");
147 void set_Gravity (PanelWindow
* panel
)
149 switch (panel
->docking
.side
)
151 case SIDE_NONE
: break;
152 case SIDE_LEFT
: gtk_window_set_gravity (GTK_WINDOW (panel
->win
), GDK_GRAVITY_WEST
); break;
153 case SIDE_RIGHT
: gtk_window_set_gravity (GTK_WINDOW (panel
->win
), GDK_GRAVITY_EAST
); break;
154 case SIDE_TOP
: gtk_window_set_gravity (GTK_WINDOW (panel
->win
), GDK_GRAVITY_NORTH
); break;
155 case SIDE_BOTTOM
: gtk_window_set_gravity (GTK_WINDOW (panel
->win
), GDK_GRAVITY_SOUTH
); break;
159 /* Internal helpers */
168 void on_resize (GtkWidget
* w
, GtkAllocation
* size
, gpointer data
)
170 if (PANEL_WINDOW (data
)->size
.request
) {
171 PANEL_WINDOW (data
)->size
.request
= FALSE
;
172 g_signal_handler_unblock (G_OBJECT (PANEL_WINDOW (data
)->win
), PANEL_WINDOW (data
)->enter_cb_id
);
173 g_signal_handler_unblock (G_OBJECT (PANEL_WINDOW (data
)->win
), PANEL_WINDOW (data
)->leave_cb_id
);
176 PANEL_WINDOW (data
)->size
.w
= size
->width
;
177 PANEL_WINDOW (data
)->size
.h
= size
->height
;
179 if (PANEL_WINDOW (data
)->docking
.side
!= SIDE_NONE
)
181 update_pos (PANEL_WINDOW (data
));
182 update_window_pos (PANEL_WINDOW (data
));
187 void on_size_request (GtkWidget
* w
, GtkRequisition
* size
, gpointer data
)
189 if (! PANEL_WINDOW (data
)->size
.request
) {
190 PANEL_WINDOW (data
)->size
.request
= TRUE
;
191 g_signal_handler_block (G_OBJECT (PANEL_WINDOW (data
)->win
), PANEL_WINDOW (data
)->enter_cb_id
);
192 g_signal_handler_block (G_OBJECT (PANEL_WINDOW (data
)->win
), PANEL_WINDOW (data
)->leave_cb_id
);
202 void slide_canceled (gpointer data
)
203 { PANEL_WINDOW (data
)->docking
.timeout
.id
= 0; }
206 gboolean
on_enter (GtkWidget
* w
, GdkEventCrossing
* ev
, gpointer data
)
208 //if (PANEL_WINDOW (data)->size.request) return FALSE;
210 /* Filter dublicate crossing for the same direction */
211 if (! PANEL_WINDOW (data
)->docking
.visible
) {
213 /* If panel is already in necessary state, but has to change from it,... */
214 if (PANEL_WINDOW (data
)->docking
.timeout
.id
)
215 /* just stop timer */
216 g_source_remove (PANEL_WINDOW (data
)->docking
.timeout
.id
);
220 if (PANEL_WINDOW (data
)->docking
.autohiding
)
222 else func
= panel_window_focus
, PANEL_WINDOW (data
)->docking
.visible
= TRUE
;
224 PANEL_WINDOW (data
)->docking
.timeout
.id
= g_timeout_add_full (
226 PANEL_WINDOW (data
)->docking
.timeout
.show
,
227 (GSourceFunc
) func
, data
, slide_canceled
);
233 gboolean
on_leave (GtkWidget
* w
, GdkEventCrossing
* ev
, gpointer data
)
235 /* Prevent misoperation on internal crossments */
236 if (ev
->detail
== GDK_NOTIFY_INFERIOR
) return FALSE
;
238 /* And on mis-crossing, possible on resizing */
239 //if (PANEL_WINDOW (data)->size.request) return FALSE;
241 /* Like in 'on_enter_slide ()' */
242 if (PANEL_WINDOW (data
)->docking
.visible
) {
243 if (PANEL_WINDOW (data
)->docking
.timeout
.id
)
244 g_source_remove (PANEL_WINDOW (data
)->docking
.timeout
.id
);
246 if (PANEL_WINDOW (data
)->docking
.autohiding
)
247 PANEL_WINDOW (data
)->docking
.timeout
.id
= g_timeout_add_full (
249 PANEL_WINDOW (data
)->docking
.timeout
.hide
,
250 (GSourceFunc
) hide
, data
, slide_canceled
);
252 PANEL_WINDOW (data
)->docking
.visible
= FALSE
;