win32: support taskbar button progress indicator

This adds support for the progress indicator taskbar extension
that was introduced with Windows 7 and Windows Server 2008 R2.

I don’t like this solution because it keeps its own state and
introduces another VOCTRL, but I couldn’t come up with anything
less messy.

closes #2399
This commit is contained in:
Martin Herkt 2015-11-15 23:03:48 +01:00
parent 883d311413
commit bf0b178e71
No known key found for this signature in database
GPG Key ID: C24B9CD04DC6AE7F
5 changed files with 67 additions and 0 deletions

View File

@ -181,6 +181,7 @@ typedef struct MPContext {
char *term_osd_subs;
char *term_osd_contents;
char *last_window_title;
struct voctrl_playback_state vo_playback_state;
int add_osd_seek_info; // bitfield of enum mp_osd_seek_info
double osd_visible; // for the osd bar only
@ -462,6 +463,7 @@ double get_relative_time(struct MPContext *mpctx);
void merge_playlist_files(struct playlist *pl);
float mp_get_cache_percent(struct MPContext *mpctx);
bool mp_get_cache_idle(struct MPContext *mpctx);
void update_vo_playback_state(struct MPContext *mpctx);
void update_window_title(struct MPContext *mpctx, bool force);
void error_on_track(struct MPContext *mpctx, struct track *track);
int stream_dump(struct MPContext *mpctx, const char *source_filename);

View File

@ -153,6 +153,26 @@ bool mp_get_cache_idle(struct MPContext *mpctx)
return idle;
}
void update_vo_playback_state(struct MPContext *mpctx)
{
if (mpctx->video_out) {
struct voctrl_playback_state oldstate = mpctx->vo_playback_state;
struct voctrl_playback_state newstate = {
.paused = mpctx->paused,
.percent_pos = get_percent_pos(mpctx),
};
if (oldstate.paused != newstate.paused ||
oldstate.percent_pos != newstate.percent_pos) {
vo_control(mpctx->video_out,
VOCTRL_UPDATE_PLAYBACK_STATE, &newstate);
mpctx->vo_playback_state = newstate;
}
} else {
mpctx->vo_playback_state = (struct voctrl_playback_state){ 0 };
}
}
void update_window_title(struct MPContext *mpctx, bool force)
{
if (!mpctx->video_out && !mpctx->ao) {

View File

@ -164,6 +164,7 @@ static void print_status(struct MPContext *mpctx)
struct MPOpts *opts = mpctx->opts;
update_window_title(mpctx, false);
update_vo_playback_state(mpctx);
if (!opts->use_terminal)
return;

View File

@ -76,6 +76,7 @@ enum mp_voctrl {
VOCTRL_ALL_WORKSPACES,
VOCTRL_UPDATE_WINDOW_TITLE, // char*
VOCTRL_UPDATE_PLAYBACK_STATE, // struct voctrl_playback_state*
VOCTRL_SET_CURSOR_VISIBILITY, // bool*
@ -130,6 +131,12 @@ struct voctrl_get_equalizer_args {
#define VO_NOTAVAIL -2
#define VO_NOTIMPL -3
// VOCTRL_UPDATE_PLAYBACK_STATE
struct voctrl_playback_state {
bool paused;
int percent_pos;
};
enum {
// VO does handle mp_image_params.rotate in 90 degree steps
VO_CAP_ROTATE90 = 1 << 0,

View File

@ -105,6 +105,9 @@ struct vo_w32_state {
int high_surrogate;
ITaskbarList2 *taskbar_list;
ITaskbarList3 *taskbar_list3;
UINT tbtnCreatedMsg;
bool tbtnCreated;
// updates on move/resize/displaychange
double display_fps;
@ -826,6 +829,11 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
break;
}
if (message == w32->tbtnCreatedMsg) {
w32->tbtnCreated = true;
return 0;
}
if (mouse_button) {
mouse_button |= mod_state(w32);
mp_input_put_key(w32->input_ctx, mouse_button);
@ -1198,6 +1206,20 @@ static void *gui_thread(void *ptr)
w32->taskbar_list = NULL;
}
}
// ITaskbarList3 has methods for status indication on taskbar buttons,
// however that interface is only available on Win7/2008 R2 or newer
if (SUCCEEDED(CoCreateInstance(&CLSID_TaskbarList, NULL,
CLSCTX_INPROC_SERVER, &IID_ITaskbarList3,
(void**)&w32->taskbar_list3)))
{
if (FAILED(ITaskbarList3_HrInit(w32->taskbar_list3))) {
ITaskbarList3_Release(w32->taskbar_list3);
w32->taskbar_list3 = NULL;
} else {
w32->tbtnCreatedMsg = RegisterWindowMessage(L"TaskbarButtonCreated");
}
}
} else {
MP_ERR(w32, "Failed to initialize OLE/COM\n");
}
@ -1235,6 +1257,8 @@ done:
}
if (w32->taskbar_list)
ITaskbarList2_Release(w32->taskbar_list);
if (w32->taskbar_list3)
ITaskbarList3_Release(w32->taskbar_list3);
if (ole_ok)
OleUninitialize();
SetThreadExecutionState(ES_CONTINUOUS);
@ -1348,6 +1372,19 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
talloc_free(title);
return VO_TRUE;
}
case VOCTRL_UPDATE_PLAYBACK_STATE: {
struct voctrl_playback_state *pstate =
(struct voctrl_playback_state *)arg;
if (w32->taskbar_list3 && w32->tbtnCreated) {
ITaskbarList3_SetProgressValue(w32->taskbar_list3, w32->window,
pstate->percent_pos, 100);
ITaskbarList3_SetProgressState(w32->taskbar_list3, w32->window,
pstate->paused ? TBPF_PAUSED :
TBPF_NORMAL);
}
return VO_TRUE;
}
case VOCTRL_GET_DISPLAY_FPS:
update_display_fps(w32);
*(double*) arg = w32->display_fps;